diff options
author | Christian Pointner <equinox@helsinki.at> | 2025-03-27 19:25:26 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2025-03-27 19:25:26 (GMT) |
commit | 007968bc72332f5058aa9d7a3ddfd2d5fbc9a0f6 (patch) | |
tree | 42188f8b75b324bc9a5ce896304620aa259ea354 /snd-pcxhr-dkms/src/pcxhr_hrtimer.c | |
parent | 7df0e67f08b759d8f9dd75726a2f7ff1d09e24b7 (diff) |
add package snd-pcxhr-dkms
Diffstat (limited to 'snd-pcxhr-dkms/src/pcxhr_hrtimer.c')
-rw-r--r-- | snd-pcxhr-dkms/src/pcxhr_hrtimer.c | 78 |
1 files changed, 78 insertions, 0 deletions
diff --git a/snd-pcxhr-dkms/src/pcxhr_hrtimer.c b/snd-pcxhr-dkms/src/pcxhr_hrtimer.c new file mode 100644 index 0000000..172b713 --- /dev/null +++ b/snd-pcxhr-dkms/src/pcxhr_hrtimer.c @@ -0,0 +1,78 @@ +/* + * Driver for Digigram pcxhr compatible soundcards + * + * Copyright (c) 2004 by Digigram <alsa@digigram.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "pcxhr_hrtimer.h" + +void pcxhr_hr_timer_tasklet(unsigned long data) +{ + pcxhr_interrupt(0, (void*)data); +} + +enum hrtimer_restart pcxhr_hr_timer_callback(struct hrtimer* hr_timer) +{ + struct pcxhr_mgr *mgr; + + mgr = container_of(hr_timer, struct pcxhr_mgr, hr_timer); + if (!atomic_read(&mgr->hr_timer_running)) + return HRTIMER_NORESTART; + tasklet_schedule(&mgr->hr_timer_tasklet); + hrtimer_forward_now(hr_timer, mgr->hr_timer_period_time); + return HRTIMER_RESTART; +} + + +void pcxhr_hr_timer_trig(struct pcxhr_mgr *mgr, int start, unsigned int rate) { + if (start) + { + unsigned int period = mgr->granularity/2; + long sec; + unsigned long nsecs; + + sec = period/rate; + period %= rate; + nsecs = div_u64((u64)period * 1000000000UL + rate - 1, rate); + + tasklet_kill(&mgr->hr_timer_tasklet); // Make sure the tasklet is not running. + mgr->hr_timer_period_time = ktime_set(sec, nsecs); + atomic_set(&mgr->hr_timer_running, 1); + hrtimer_start(&mgr->hr_timer, mgr->hr_timer_period_time, HRTIMER_MODE_REL); + } + else + { + atomic_set(&mgr->hr_timer_running, 0); + hrtimer_cancel(&mgr->hr_timer); + } + +} + + +void pcxhr_hr_timer_init(struct pcxhr_mgr *mgr) { + hrtimer_init( &mgr->hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL ); + mgr->hr_timer.function = pcxhr_hr_timer_callback; + atomic_set(&mgr->hr_timer_running, 0); + tasklet_init(&mgr->hr_timer_tasklet, pcxhr_hr_timer_tasklet, + (unsigned long)mgr); + +} + +void pcxhr_hr_timer_kill(struct pcxhr_mgr *mgr) { + tasklet_kill(&mgr->hr_timer_tasklet); +} |