diff options
| -rw-r--r-- | sound/drivers/pcsp/pcsp_lib.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index ac6238e93513..54253e9b4b02 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c | |||
| @@ -18,6 +18,8 @@ module_param(nforce_wa, bool, 0444); | |||
| 18 | MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " | 18 | MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround " |
| 19 | "(expect bad sound)"); | 19 | "(expect bad sound)"); |
| 20 | 20 | ||
| 21 | #define DMIX_WANTS_S16 1 | ||
| 22 | |||
| 21 | static void pcsp_start_timer(unsigned long dummy) | 23 | static void pcsp_start_timer(unsigned long dummy) |
| 22 | { | 24 | { |
| 23 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); | 25 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); |
| @@ -47,7 +49,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
| 47 | { | 49 | { |
| 48 | unsigned long flags; | 50 | unsigned long flags; |
| 49 | unsigned char timer_cnt, val; | 51 | unsigned char timer_cnt, val; |
| 50 | int periods_elapsed; | 52 | int fmt_size, periods_elapsed; |
| 51 | u64 ns; | 53 | u64 ns; |
| 52 | size_t period_bytes, buffer_bytes; | 54 | size_t period_bytes, buffer_bytes; |
| 53 | struct snd_pcm_substream *substream; | 55 | struct snd_pcm_substream *substream; |
| @@ -92,8 +94,11 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
| 92 | goto exit_nr_unlock2; | 94 | goto exit_nr_unlock2; |
| 93 | 95 | ||
| 94 | runtime = substream->runtime; | 96 | runtime = substream->runtime; |
| 95 | /* assume it is u8 mono */ | 97 | fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3; |
| 96 | val = runtime->dma_area[chip->playback_ptr]; | 98 | /* assume it is mono! */ |
| 99 | val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; | ||
| 100 | if (snd_pcm_format_signed(runtime->format)) | ||
| 101 | val ^= 0x80; | ||
| 97 | timer_cnt = val * CUR_DIV() / 256; | 102 | timer_cnt = val * CUR_DIV() / 256; |
| 98 | 103 | ||
| 99 | if (timer_cnt && chip->enable) { | 104 | if (timer_cnt && chip->enable) { |
| @@ -111,7 +116,7 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
| 111 | 116 | ||
| 112 | period_bytes = snd_pcm_lib_period_bytes(substream); | 117 | period_bytes = snd_pcm_lib_period_bytes(substream); |
| 113 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); | 118 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); |
| 114 | chip->playback_ptr += PCSP_INDEX_INC(); | 119 | chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; |
| 115 | periods_elapsed = chip->playback_ptr - chip->period_ptr; | 120 | periods_elapsed = chip->playback_ptr - chip->period_ptr; |
| 116 | if (periods_elapsed < 0) { | 121 | if (periods_elapsed < 0) { |
| 117 | printk(KERN_WARNING "PCSP: playback_ptr inconsistent " | 122 | printk(KERN_WARNING "PCSP: playback_ptr inconsistent " |
| @@ -270,7 +275,11 @@ static struct snd_pcm_hardware snd_pcsp_playback = { | |||
| 270 | .info = (SNDRV_PCM_INFO_INTERLEAVED | | 275 | .info = (SNDRV_PCM_INFO_INTERLEAVED | |
| 271 | SNDRV_PCM_INFO_HALF_DUPLEX | | 276 | SNDRV_PCM_INFO_HALF_DUPLEX | |
| 272 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), | 277 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID), |
| 273 | .formats = SNDRV_PCM_FMTBIT_U8, | 278 | .formats = (SNDRV_PCM_FMTBIT_U8 |
| 279 | #if DMIX_WANTS_S16 | ||
| 280 | | SNDRV_PCM_FMTBIT_S16_LE | ||
| 281 | #endif | ||
| 282 | ), | ||
| 274 | .rates = SNDRV_PCM_RATE_KNOT, | 283 | .rates = SNDRV_PCM_RATE_KNOT, |
| 275 | .rate_min = PCSP_DEFAULT_SRATE, | 284 | .rate_min = PCSP_DEFAULT_SRATE, |
| 276 | .rate_max = PCSP_DEFAULT_SRATE, | 285 | .rate_max = PCSP_DEFAULT_SRATE, |
