diff options
Diffstat (limited to 'sound/pci/oxygen/oxygen_pcm.c')
-rw-r--r-- | sound/pci/oxygen/oxygen_pcm.c | 55 |
1 files changed, 34 insertions, 21 deletions
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 814667442eb0..d5533e34ece9 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c | |||
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { | |||
39 | SNDRV_PCM_INFO_MMAP_VALID | | 39 | SNDRV_PCM_INFO_MMAP_VALID | |
40 | SNDRV_PCM_INFO_INTERLEAVED | | 40 | SNDRV_PCM_INFO_INTERLEAVED | |
41 | SNDRV_PCM_INFO_PAUSE | | 41 | SNDRV_PCM_INFO_PAUSE | |
42 | SNDRV_PCM_INFO_SYNC_START, | 42 | SNDRV_PCM_INFO_SYNC_START | |
43 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, | ||
43 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 44 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
44 | SNDRV_PCM_FMTBIT_S32_LE, | 45 | SNDRV_PCM_FMTBIT_S32_LE, |
45 | .rates = SNDRV_PCM_RATE_32000 | | 46 | .rates = SNDRV_PCM_RATE_32000 | |
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { | |||
65 | SNDRV_PCM_INFO_MMAP_VALID | | 66 | SNDRV_PCM_INFO_MMAP_VALID | |
66 | SNDRV_PCM_INFO_INTERLEAVED | | 67 | SNDRV_PCM_INFO_INTERLEAVED | |
67 | SNDRV_PCM_INFO_PAUSE | | 68 | SNDRV_PCM_INFO_PAUSE | |
68 | SNDRV_PCM_INFO_SYNC_START, | 69 | SNDRV_PCM_INFO_SYNC_START | |
70 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, | ||
69 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 71 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
70 | SNDRV_PCM_FMTBIT_S32_LE, | 72 | SNDRV_PCM_FMTBIT_S32_LE, |
71 | .rates = SNDRV_PCM_RATE_32000 | | 73 | .rates = SNDRV_PCM_RATE_32000 | |
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { | |||
91 | SNDRV_PCM_INFO_MMAP_VALID | | 93 | SNDRV_PCM_INFO_MMAP_VALID | |
92 | SNDRV_PCM_INFO_INTERLEAVED | | 94 | SNDRV_PCM_INFO_INTERLEAVED | |
93 | SNDRV_PCM_INFO_PAUSE | | 95 | SNDRV_PCM_INFO_PAUSE | |
94 | SNDRV_PCM_INFO_SYNC_START, | 96 | SNDRV_PCM_INFO_SYNC_START | |
97 | SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, | ||
95 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 98 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
96 | .rates = SNDRV_PCM_RATE_48000, | 99 | .rates = SNDRV_PCM_RATE_48000, |
97 | .rate_min = 48000, | 100 | .rate_min = 48000, |
@@ -140,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, | |||
140 | runtime->hw.rate_min = 44100; | 143 | runtime->hw.rate_min = 44100; |
141 | break; | 144 | break; |
142 | case PCM_MULTICH: | 145 | case PCM_MULTICH: |
143 | runtime->hw.channels_max = chip->model.dac_channels; | 146 | runtime->hw.channels_max = chip->model.dac_channels_pcm; |
144 | break; | 147 | break; |
145 | } | 148 | } |
146 | if (chip->model.pcm_hardware_filter) | 149 | if (chip->model.pcm_hardware_filter) |
@@ -271,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params) | |||
271 | } | 274 | } |
272 | } | 275 | } |
273 | 276 | ||
274 | unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, | ||
275 | unsigned int channel, | ||
276 | struct snd_pcm_hw_params *hw_params) | ||
277 | { | ||
278 | if (params_rate(hw_params) <= 96000) | ||
279 | return OXYGEN_I2S_MCLK_256; | ||
280 | else | ||
281 | return OXYGEN_I2S_MCLK_128; | ||
282 | } | ||
283 | EXPORT_SYMBOL(oxygen_default_i2s_mclk); | ||
284 | |||
285 | static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) | 277 | static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) |
286 | { | 278 | { |
287 | if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) | 279 | if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) |
@@ -341,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream, | |||
341 | return 0; | 333 | return 0; |
342 | } | 334 | } |
343 | 335 | ||
336 | static u16 get_mclk(struct oxygen *chip, unsigned int channel, | ||
337 | struct snd_pcm_hw_params *params) | ||
338 | { | ||
339 | unsigned int mclks, shift; | ||
340 | |||
341 | if (channel == PCM_MULTICH) | ||
342 | mclks = chip->model.dac_mclks; | ||
343 | else | ||
344 | mclks = chip->model.adc_mclks; | ||
345 | |||
346 | if (params_rate(params) <= 48000) | ||
347 | shift = 0; | ||
348 | else if (params_rate(params) <= 96000) | ||
349 | shift = 2; | ||
350 | else | ||
351 | shift = 4; | ||
352 | |||
353 | return OXYGEN_I2S_MCLK(mclks >> shift); | ||
354 | } | ||
355 | |||
344 | static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, | 356 | static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, |
345 | struct snd_pcm_hw_params *hw_params) | 357 | struct snd_pcm_hw_params *hw_params) |
346 | { | 358 | { |
@@ -357,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, | |||
357 | OXYGEN_REC_FORMAT_A_MASK); | 369 | OXYGEN_REC_FORMAT_A_MASK); |
358 | oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, | 370 | oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, |
359 | oxygen_rate(hw_params) | | 371 | oxygen_rate(hw_params) | |
360 | chip->model.get_i2s_mclk(chip, PCM_A, hw_params) | | ||
361 | chip->model.adc_i2s_format | | 372 | chip->model.adc_i2s_format | |
373 | get_mclk(chip, PCM_A, hw_params) | | ||
362 | oxygen_i2s_bits(hw_params), | 374 | oxygen_i2s_bits(hw_params), |
363 | OXYGEN_I2S_RATE_MASK | | 375 | OXYGEN_I2S_RATE_MASK | |
364 | OXYGEN_I2S_FORMAT_MASK | | 376 | OXYGEN_I2S_FORMAT_MASK | |
@@ -393,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, | |||
393 | if (!is_ac97) | 405 | if (!is_ac97) |
394 | oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, | 406 | oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, |
395 | oxygen_rate(hw_params) | | 407 | oxygen_rate(hw_params) | |
396 | chip->model.get_i2s_mclk(chip, PCM_B, | ||
397 | hw_params) | | ||
398 | chip->model.adc_i2s_format | | 408 | chip->model.adc_i2s_format | |
409 | get_mclk(chip, PCM_B, hw_params) | | ||
399 | oxygen_i2s_bits(hw_params), | 410 | oxygen_i2s_bits(hw_params), |
400 | OXYGEN_I2S_RATE_MASK | | 411 | OXYGEN_I2S_RATE_MASK | |
401 | OXYGEN_I2S_FORMAT_MASK | | 412 | OXYGEN_I2S_FORMAT_MASK | |
@@ -476,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream, | |||
476 | oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, | 487 | oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, |
477 | oxygen_rate(hw_params) | | 488 | oxygen_rate(hw_params) | |
478 | chip->model.dac_i2s_format | | 489 | chip->model.dac_i2s_format | |
479 | chip->model.get_i2s_mclk(chip, PCM_MULTICH, | 490 | get_mclk(chip, PCM_MULTICH, hw_params) | |
480 | hw_params) | | ||
481 | oxygen_i2s_bits(hw_params), | 491 | oxygen_i2s_bits(hw_params), |
482 | OXYGEN_I2S_RATE_MASK | | 492 | OXYGEN_I2S_RATE_MASK | |
483 | OXYGEN_I2S_FORMAT_MASK | | 493 | OXYGEN_I2S_FORMAT_MASK | |
@@ -530,7 +540,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream) | |||
530 | oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); | 540 | oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); |
531 | oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); | 541 | oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); |
532 | 542 | ||
533 | chip->interrupt_mask |= channel_mask; | 543 | if (substream->runtime->no_period_wakeup) |
544 | chip->interrupt_mask &= ~channel_mask; | ||
545 | else | ||
546 | chip->interrupt_mask |= channel_mask; | ||
534 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); | 547 | oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); |
535 | spin_unlock_irq(&chip->reg_lock); | 548 | spin_unlock_irq(&chip->reg_lock); |
536 | return 0; | 549 | return 0; |