summaryrefslogtreecommitdiff
path: root/snd-pcxhr/src/pcxhr_hrtimer.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2025-05-08 17:45:06 (GMT)
committerChristian Pointner <equinox@helsinki.at>2025-05-08 17:45:06 (GMT)
commite540c2f827bd7c81915b00000e440d91b450b034 (patch)
treefd0525b5425220413f4a54434b1eeb1a2c7a2f56 /snd-pcxhr/src/pcxhr_hrtimer.c
parent829bf65b9d6813528cf83a99503955d8894b5bde (diff)
snd-pcxhr: split package up into dkms source and firmwareHEADmaster
Diffstat (limited to 'snd-pcxhr/src/pcxhr_hrtimer.c')
-rw-r--r--snd-pcxhr/src/pcxhr_hrtimer.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/snd-pcxhr/src/pcxhr_hrtimer.c b/snd-pcxhr/src/pcxhr_hrtimer.c
new file mode 100644
index 0000000..4ccc1bf
--- /dev/null
+++ b/snd-pcxhr/src/pcxhr_hrtimer.c
@@ -0,0 +1,65 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Driver for Digigram pcxhr compatible soundcards
+ *
+ * Copyright (c) 2004 by Digigram <alsa@digigram.com>
+ */
+
+
+#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);
+}