+static gboolean sigma_location_is_eq(struct sigma_location *loc1,
+ struct sigma_location *loc2, gboolean with_event)
+{
+
+ if (!loc1 || !loc2)
+ return FALSE;
+
+ if (loc1->line != loc2->line)
+ return FALSE;
+ if (loc1->cluster != loc2->cluster)
+ return FALSE;
+
+ if (with_event && loc1->event != loc2->event)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Decrement the broken-down location fields (leave 'raw' as is). */
+static void sigma_location_decrement(struct sigma_location *loc,
+ gboolean with_event)
+{
+
+ if (!loc)
+ return;
+
+ if (with_event) {
+ if (loc->event--)
+ return;
+ loc->event = EVENTS_PER_CLUSTER - 1;
+ }
+
+ if (loc->cluster--)
+ return;
+ loc->cluster = CLUSTERS_PER_ROW - 1;
+
+ if (loc->line--)
+ return;
+ loc->line = ROW_COUNT - 1;
+}
+
+static void sigma_location_increment(struct sigma_location *loc)
+{
+
+ if (!loc)
+ return;
+
+ if (++loc->event < EVENTS_PER_CLUSTER)
+ return;
+ loc->event = 0;
+ if (++loc->cluster < CLUSTERS_PER_ROW)
+ return;
+ loc->cluster = 0;
+ if (++loc->line < ROW_COUNT)
+ return;
+ loc->line = 0;
+}
+
+/*
+ * Determine the position where to open the period of trigger match
+ * checks. Setup an "impossible" location when triggers are not used.
+ * Start from the hardware provided 'trig' position otherwise, and
+ * go back a few clusters, but don't go before the 'start' position.
+ */
+static void rewind_trig_arm_pos(struct dev_context *devc, size_t count)
+{
+ struct sigma_sample_interp *interp;
+
+ if (!devc)
+ return;
+ interp = &devc->interp;
+
+ if (!devc->use_triggers) {
+ interp->trig_arm.raw = ~0;
+ sigma_location_break_down(&interp->trig_arm);
+ return;
+ }
+
+ interp->trig_arm = interp->trig;
+ while (count--) {
+ if (sigma_location_is_eq(&interp->trig_arm, &interp->start, TRUE))
+ break;
+ sigma_location_decrement(&interp->trig_arm, TRUE);
+ }
+}
+