diff options
| -rw-r--r-- | sound/drivers/pcsp/pcsp_lib.c | 65 | ||||
| -rw-r--r-- | sound/drivers/pcsp/pcsp_mixer.c | 2 |
2 files changed, 35 insertions, 32 deletions
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c index 84cc2658c05b..e1145ac6e908 100644 --- a/sound/drivers/pcsp/pcsp_lib.c +++ b/sound/drivers/pcsp/pcsp_lib.c | |||
| @@ -39,25 +39,20 @@ static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0); | |||
| 39 | /* write the port and returns the next expire time in ns; | 39 | /* write the port and returns the next expire time in ns; |
| 40 | * called at the trigger-start and in hrtimer callback | 40 | * called at the trigger-start and in hrtimer callback |
| 41 | */ | 41 | */ |
| 42 | static unsigned long pcsp_timer_update(struct hrtimer *handle) | 42 | static u64 pcsp_timer_update(struct snd_pcsp *chip) |
| 43 | { | 43 | { |
| 44 | unsigned char timer_cnt, val; | 44 | unsigned char timer_cnt, val; |
| 45 | u64 ns; | 45 | u64 ns; |
| 46 | struct snd_pcm_substream *substream; | 46 | struct snd_pcm_substream *substream; |
| 47 | struct snd_pcm_runtime *runtime; | 47 | struct snd_pcm_runtime *runtime; |
| 48 | struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); | ||
| 49 | unsigned long flags; | 48 | unsigned long flags; |
| 50 | 49 | ||
| 51 | if (chip->thalf) { | 50 | if (chip->thalf) { |
| 52 | outb(chip->val61, 0x61); | 51 | outb(chip->val61, 0x61); |
| 53 | chip->thalf = 0; | 52 | chip->thalf = 0; |
| 54 | if (!atomic_read(&chip->timer_active)) | ||
| 55 | return 0; | ||
| 56 | return chip->ns_rem; | 53 | return chip->ns_rem; |
| 57 | } | 54 | } |
| 58 | 55 | ||
| 59 | if (!atomic_read(&chip->timer_active)) | ||
| 60 | return 0; | ||
| 61 | substream = chip->playback_substream; | 56 | substream = chip->playback_substream; |
| 62 | if (!substream) | 57 | if (!substream) |
| 63 | return 0; | 58 | return 0; |
| @@ -88,24 +83,17 @@ static unsigned long pcsp_timer_update(struct hrtimer *handle) | |||
| 88 | return ns; | 83 | return ns; |
| 89 | } | 84 | } |
| 90 | 85 | ||
| 91 | enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | 86 | static void pcsp_pointer_update(struct snd_pcsp *chip) |
| 92 | { | 87 | { |
| 93 | struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); | ||
| 94 | struct snd_pcm_substream *substream; | 88 | struct snd_pcm_substream *substream; |
| 95 | int periods_elapsed, pointer_update; | ||
| 96 | size_t period_bytes, buffer_bytes; | 89 | size_t period_bytes, buffer_bytes; |
| 97 | unsigned long ns; | 90 | int periods_elapsed; |
| 98 | unsigned long flags; | 91 | unsigned long flags; |
| 99 | 92 | ||
| 100 | pointer_update = !chip->thalf; | ||
| 101 | ns = pcsp_timer_update(handle); | ||
| 102 | if (!ns) | ||
| 103 | return HRTIMER_NORESTART; | ||
| 104 | |||
| 105 | /* update the playback position */ | 93 | /* update the playback position */ |
| 106 | substream = chip->playback_substream; | 94 | substream = chip->playback_substream; |
| 107 | if (!substream) | 95 | if (!substream) |
| 108 | return HRTIMER_NORESTART; | 96 | return; |
| 109 | 97 | ||
| 110 | period_bytes = snd_pcm_lib_period_bytes(substream); | 98 | period_bytes = snd_pcm_lib_period_bytes(substream); |
| 111 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); | 99 | buffer_bytes = snd_pcm_lib_buffer_bytes(substream); |
| @@ -134,6 +122,26 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
| 134 | 122 | ||
| 135 | if (periods_elapsed) | 123 | if (periods_elapsed) |
| 136 | tasklet_schedule(&pcsp_pcm_tasklet); | 124 | tasklet_schedule(&pcsp_pcm_tasklet); |
| 125 | } | ||
| 126 | |||
| 127 | enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | ||
| 128 | { | ||
| 129 | struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); | ||
| 130 | int pointer_update; | ||
| 131 | u64 ns; | ||
| 132 | |||
| 133 | if (!atomic_read(&chip->timer_active) || !chip->playback_substream) | ||
| 134 | return HRTIMER_NORESTART; | ||
| 135 | |||
| 136 | pointer_update = !chip->thalf; | ||
| 137 | ns = pcsp_timer_update(chip); | ||
| 138 | if (!ns) { | ||
| 139 | printk(KERN_WARNING "PCSP: unexpected stop\n"); | ||
| 140 | return HRTIMER_NORESTART; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (pointer_update) | ||
| 144 | pcsp_pointer_update(chip); | ||
| 137 | 145 | ||
| 138 | hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); | 146 | hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns)); |
| 139 | 147 | ||
| @@ -142,8 +150,6 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) | |||
| 142 | 150 | ||
| 143 | static int pcsp_start_playing(struct snd_pcsp *chip) | 151 | static int pcsp_start_playing(struct snd_pcsp *chip) |
| 144 | { | 152 | { |
| 145 | unsigned long ns; | ||
| 146 | |||
| 147 | #if PCSP_DEBUG | 153 | #if PCSP_DEBUG |
| 148 | printk(KERN_INFO "PCSP: start_playing called\n"); | 154 | printk(KERN_INFO "PCSP: start_playing called\n"); |
| 149 | #endif | 155 | #endif |
| @@ -159,11 +165,7 @@ static int pcsp_start_playing(struct snd_pcsp *chip) | |||
| 159 | atomic_set(&chip->timer_active, 1); | 165 | atomic_set(&chip->timer_active, 1); |
| 160 | chip->thalf = 0; | 166 | chip->thalf = 0; |
| 161 | 167 | ||
| 162 | ns = pcsp_timer_update(&pcsp_chip.timer); | 168 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); |
| 163 | if (!ns) | ||
| 164 | return -EIO; | ||
| 165 | |||
| 166 | hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL); | ||
| 167 | return 0; | 169 | return 0; |
| 168 | } | 170 | } |
| 169 | 171 | ||
| @@ -232,21 +234,22 @@ static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) | |||
| 232 | static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) | 234 | static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream) |
| 233 | { | 235 | { |
| 234 | struct snd_pcsp *chip = snd_pcm_substream_chip(substream); | 236 | struct snd_pcsp *chip = snd_pcm_substream_chip(substream); |
| 237 | pcsp_sync_stop(chip); | ||
| 238 | chip->playback_ptr = 0; | ||
| 239 | chip->period_ptr = 0; | ||
| 240 | chip->fmt_size = | ||
| 241 | snd_pcm_format_physical_width(substream->runtime->format) >> 3; | ||
| 242 | chip->is_signed = snd_pcm_format_signed(substream->runtime->format); | ||
| 235 | #if PCSP_DEBUG | 243 | #if PCSP_DEBUG |
| 236 | printk(KERN_INFO "PCSP: prepare called, " | 244 | printk(KERN_INFO "PCSP: prepare called, " |
| 237 | "size=%zi psize=%zi f=%zi f1=%i\n", | 245 | "size=%zi psize=%zi f=%zi f1=%i fsize=%i\n", |
| 238 | snd_pcm_lib_buffer_bytes(substream), | 246 | snd_pcm_lib_buffer_bytes(substream), |
| 239 | snd_pcm_lib_period_bytes(substream), | 247 | snd_pcm_lib_period_bytes(substream), |
| 240 | snd_pcm_lib_buffer_bytes(substream) / | 248 | snd_pcm_lib_buffer_bytes(substream) / |
| 241 | snd_pcm_lib_period_bytes(substream), | 249 | snd_pcm_lib_period_bytes(substream), |
| 242 | substream->runtime->periods); | 250 | substream->runtime->periods, |
| 251 | chip->fmt_size); | ||
| 243 | #endif | 252 | #endif |
| 244 | pcsp_sync_stop(chip); | ||
| 245 | chip->playback_ptr = 0; | ||
| 246 | chip->period_ptr = 0; | ||
| 247 | chip->fmt_size = | ||
| 248 | snd_pcm_format_physical_width(substream->runtime->format) >> 3; | ||
| 249 | chip->is_signed = snd_pcm_format_signed(substream->runtime->format); | ||
| 250 | return 0; | 253 | return 0; |
| 251 | } | 254 | } |
| 252 | 255 | ||
diff --git a/sound/drivers/pcsp/pcsp_mixer.c b/sound/drivers/pcsp/pcsp_mixer.c index 199b03377142..903bc846763f 100644 --- a/sound/drivers/pcsp/pcsp_mixer.c +++ b/sound/drivers/pcsp/pcsp_mixer.c | |||
| @@ -72,7 +72,7 @@ static int pcsp_treble_put(struct snd_kcontrol *kcontrol, | |||
| 72 | if (treble != chip->treble) { | 72 | if (treble != chip->treble) { |
| 73 | chip->treble = treble; | 73 | chip->treble = treble; |
| 74 | #if PCSP_DEBUG | 74 | #if PCSP_DEBUG |
| 75 | printk(KERN_INFO "PCSP: rate set to %i\n", PCSP_RATE()); | 75 | printk(KERN_INFO "PCSP: rate set to %li\n", PCSP_RATE()); |
| 76 | #endif | 76 | #endif |
| 77 | changed = 1; | 77 | changed = 1; |
| 78 | } | 78 | } |
