diff options
Diffstat (limited to 'sound/drivers/pcsp')
-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 ac6238e9351..54253e9b4b0 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, |