mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Oskar Schirmer" <os@emlix.com>
To: Sascha Hauer <kernel@pengutronix.de>
Cc: linux-kernel@vger.kernel.org, Oskar Schirmer <os@emlix.com>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: [PATCH 6/8] lib: isolate rational fractions helper function
Date: Tue,  9 Jun 2009 15:46:49 +0200	[thread overview]
Message-ID: <1244555211-15618-7-git-send-email-os@emlix.com> (raw)
In-Reply-To: <1244555211-15618-6-git-send-email-os@emlix.com>

Provide a helper function to determine optimum numerator
denominator value pairs taking into account restricted
register size. Useful especially with PLL and other clock
configurations.

Signed-off-by: Oskar Schirmer <os@emlix.com>
---
 include/linux/rational.h |   19 ++++++++++++++
 lib/Kconfig              |    3 ++
 lib/Makefile             |    1 +
 lib/rational.c           |   60 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 83 insertions(+), 0 deletions(-)
 create mode 100644 include/linux/rational.h
 create mode 100644 lib/rational.c

diff --git a/include/linux/rational.h b/include/linux/rational.h
new file mode 100644
index 0000000..4f532fc
--- /dev/null
+++ b/include/linux/rational.h
@@ -0,0 +1,19 @@
+/*
+ * rational fractions
+ *
+ * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <os@emlix.com>
+ *
+ * helper functions when coping with rational numbers,
+ * e.g. when calculating optimum numerator/denominator pairs for
+ * pll configuration taking into account restricted register size
+ */
+
+#ifndef _LINUX_RATIONAL_H
+#define _LINUX_RATIONAL_H
+
+void rational_best_approximation(
+	unsigned long given_numerator, unsigned long given_denominator,
+	unsigned long max_numerator, unsigned long max_denominator,
+	unsigned long *best_numerator, unsigned long *best_denominator);
+
+#endif /* _LINUX_RATIONAL_H */
diff --git a/lib/Kconfig b/lib/Kconfig
index 8ade0a7..9960be0 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -10,6 +10,9 @@ menu "Library routines"
 config BITREVERSE
 	tristate
 
+config RATIONAL
+	boolean
+
 config GENERIC_FIND_FIRST_BIT
 	bool
 
diff --git a/lib/Makefile b/lib/Makefile
index 33a40e4..1f6edef 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -50,6 +50,7 @@ ifneq ($(CONFIG_HAVE_DEC_LOCK),y)
 endif
 
 obj-$(CONFIG_BITREVERSE) += bitrev.o
+obj-$(CONFIG_RATIONAL)	+= rational.o
 obj-$(CONFIG_CRC_CCITT)	+= crc-ccitt.o
 obj-$(CONFIG_CRC16)	+= crc16.o
 obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
diff --git a/lib/rational.c b/lib/rational.c
new file mode 100644
index 0000000..76f5a0c
--- /dev/null
+++ b/lib/rational.c
@@ -0,0 +1,60 @@
+/*
+ * rational fractions
+ *
+ * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <os@emlix.com>
+ *
+ * helper functions when coping with rational numbers
+ */
+
+#include <linux/rational.h>
+
+/*
+ * calculate best rational approximation for a given fraction
+ * taking into account restricted register size, e.g. to find
+ * appropriate values for a pll with 5 bit denominator and
+ * 8 bit numerator register fields, trying to set up with a
+ * frequency ratio of 3.1415, one would say:
+ *
+ * rational_best_approximation(31415, 10000,
+ *		(1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+
+void rational_best_approximation(
+	unsigned long given_numerator, unsigned long given_denominator,
+	unsigned long max_numerator, unsigned long max_denominator,
+	unsigned long *best_numerator, unsigned long *best_denominator)
+{
+	unsigned long n, d, n0, d0, n1, d1;
+	n = given_numerator;
+	d = given_denominator;
+	n0 = d1 = 0;
+	n1 = d0 = 1;
+	for (;;) {
+		unsigned long t, a;
+		if ((n1 > max_numerator) || (d1 > max_denominator)) {
+			n1 = n0;
+			d1 = d0;
+			break;
+		}
+		if (d == 0)
+			break;
+		t = d;
+		a = n / d;
+		d = n % d;
+		n = t;
+		t = n0 + a * n1;
+		n0 = n1;
+		n1 = t;
+		t = d0 + a * d1;
+		d0 = d1;
+		d1 = t;
+	}
+	*best_numerator = n1;
+	*best_denominator = d1;
+}
-- 
1.5.3.7


  reply	other threads:[~2009-06-09 13:48 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-06-09 13:46 imx: serial: add IrDA support to serial driver Oskar Schirmer
2009-06-09 13:46 ` [PATCH 1/8] imx: serial: fix whitespaces (no changes in functionality) Oskar Schirmer
2009-06-09 13:46   ` [PATCH 2/8] imx: serial: fix one bit field type Oskar Schirmer
2009-06-09 13:46     ` [PATCH 3/8] imx: serial: notify higher layers in case xmit IRQ was not called Oskar Schirmer
2009-06-09 13:46       ` [PATCH 4/8] imx: serial: be sure to stop xmit upon shutdown Oskar Schirmer
2009-06-09 13:46         ` [PATCH 5/8] imx: serial: handle initialisation failure correctly Oskar Schirmer
2009-06-09 13:46           ` Oskar Schirmer [this message]
2009-06-09 13:46             ` [PATCH 7/8] imx: serial: use rational library function Oskar Schirmer
2009-06-09 13:46               ` [PATCH 8/8] imx: serial: add IrDA support to serial driver Oskar Schirmer
2009-06-09 15:01                 ` Alan Cox
2009-06-09 16:18                   ` Oskar Schirmer
2009-06-09 17:07                     ` Alan Cox
2009-06-09 18:04                       ` Oskar Schirmer
2009-06-09 18:10                 ` Sascha Hauer
2009-06-10  7:00                   ` Oskar Schirmer
2009-06-09 18:13             ` [PATCH 6/8] lib: isolate rational fractions helper function Sascha Hauer
2009-06-09 18:29 ` imx: serial: add IrDA support to serial driver Sascha Hauer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1244555211-15618-7-git-send-email-os@emlix.com \
    --to=os@emlix.com \
    --cc=akpm@linux-foundation.org \
    --cc=kernel@pengutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome