Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42621782 authored by Nicholas Troast's avatar Nicholas Troast Committed by Subbaraman Narayanamurthy
Browse files

power: fg-util: add median filter for circular buffer



A median filter is useful for filtering out outliers. Add it.

Change-Id: I21f97a870c262e5fb3d33b8250a2bf074f519b58
Signed-off-by: default avatarNicholas Troast <ntroast@codeaurora.org>
Signed-off-by: default avatarAbhijeet Dharmapurikar <adharmap@codeaurora.org>
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent 19258928
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -325,7 +325,7 @@ struct fg_irq_info {
};

struct fg_circ_buf {
	int	arr[20];
	int	arr[10];
	int	size;
	int	head;
};
@@ -504,6 +504,7 @@ extern bool is_qnovo_en(struct fg_chip *chip);
extern void fg_circ_buf_add(struct fg_circ_buf *buf, int val);
extern void fg_circ_buf_clr(struct fg_circ_buf *buf);
extern int fg_circ_buf_avg(struct fg_circ_buf *buf, int *avg);
extern int fg_circ_buf_median(struct fg_circ_buf *buf, int *median);
extern int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input,
			s32 *output);
#endif
+34 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
 * GNU General Public License for more details.
 */

#include <linux/sort.h>
#include "fg-core.h"

void fg_circ_buf_add(struct fg_circ_buf *buf, int val)
@@ -39,6 +40,39 @@ int fg_circ_buf_avg(struct fg_circ_buf *buf, int *avg)
	return 0;
}

static int cmp_int(const void *a, const void *b)
{
	return *(int *)a - *(int *)b;
}

int fg_circ_buf_median(struct fg_circ_buf *buf, int *median)
{
	int *temp;

	if (buf->size == 0)
		return -ENODATA;

	if (buf->size == 1) {
		*median = buf->arr[0];
		return 0;
	}

	temp = kmalloc_array(buf->size, sizeof(*temp), GFP_KERNEL);
	if (!temp)
		return -ENOMEM;

	memcpy(temp, buf->arr, buf->size * sizeof(*temp));
	sort(temp, buf->size, sizeof(*temp), cmp_int, NULL);

	if (buf->size % 2)
		*median = temp[buf->size / 2];
	else
		*median = (temp[buf->size / 2 - 1] + temp[buf->size / 2]) / 2;

	kfree(temp);
	return 0;
}

int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input, s32 *output)
{
	int i;