Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib: isolate rational fractions helper function

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>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Oskar Schirmer and committed by
Linus Torvalds
8759ef32 9f322ad0

+85
+19
include/linux/rational.h
··· 1 + /* 2 + * rational fractions 3 + * 4 + * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <os@emlix.com> 5 + * 6 + * helper functions when coping with rational numbers, 7 + * e.g. when calculating optimum numerator/denominator pairs for 8 + * pll configuration taking into account restricted register size 9 + */ 10 + 11 + #ifndef _LINUX_RATIONAL_H 12 + #define _LINUX_RATIONAL_H 13 + 14 + void rational_best_approximation( 15 + unsigned long given_numerator, unsigned long given_denominator, 16 + unsigned long max_numerator, unsigned long max_denominator, 17 + unsigned long *best_numerator, unsigned long *best_denominator); 18 + 19 + #endif /* _LINUX_RATIONAL_H */
+3
lib/Kconfig
··· 10 10 config BITREVERSE 11 11 tristate 12 12 13 + config RATIONAL 14 + boolean 15 + 13 16 config GENERIC_FIND_FIRST_BIT 14 17 bool 15 18
+1
lib/Makefile
··· 50 50 endif 51 51 52 52 obj-$(CONFIG_BITREVERSE) += bitrev.o 53 + obj-$(CONFIG_RATIONAL) += rational.o 53 54 obj-$(CONFIG_CRC_CCITT) += crc-ccitt.o 54 55 obj-$(CONFIG_CRC16) += crc16.o 55 56 obj-$(CONFIG_CRC_T10DIF)+= crc-t10dif.o
+62
lib/rational.c
··· 1 + /* 2 + * rational fractions 3 + * 4 + * Copyright (C) 2009 emlix GmbH, Oskar Schirmer <os@emlix.com> 5 + * 6 + * helper functions when coping with rational numbers 7 + */ 8 + 9 + #include <linux/rational.h> 10 + 11 + /* 12 + * calculate best rational approximation for a given fraction 13 + * taking into account restricted register size, e.g. to find 14 + * appropriate values for a pll with 5 bit denominator and 15 + * 8 bit numerator register fields, trying to set up with a 16 + * frequency ratio of 3.1415, one would say: 17 + * 18 + * rational_best_approximation(31415, 10000, 19 + * (1 << 8) - 1, (1 << 5) - 1, &n, &d); 20 + * 21 + * you may look at given_numerator as a fixed point number, 22 + * with the fractional part size described in given_denominator. 23 + * 24 + * for theoretical background, see: 25 + * http://en.wikipedia.org/wiki/Continued_fraction 26 + */ 27 + 28 + void rational_best_approximation( 29 + unsigned long given_numerator, unsigned long given_denominator, 30 + unsigned long max_numerator, unsigned long max_denominator, 31 + unsigned long *best_numerator, unsigned long *best_denominator) 32 + { 33 + unsigned long n, d, n0, d0, n1, d1; 34 + n = given_numerator; 35 + d = given_denominator; 36 + n0 = d1 = 0; 37 + n1 = d0 = 1; 38 + for (;;) { 39 + unsigned long t, a; 40 + if ((n1 > max_numerator) || (d1 > max_denominator)) { 41 + n1 = n0; 42 + d1 = d0; 43 + break; 44 + } 45 + if (d == 0) 46 + break; 47 + t = d; 48 + a = n / d; 49 + d = n % d; 50 + n = t; 51 + t = n0 + a * n1; 52 + n0 = n1; 53 + n1 = t; 54 + t = d0 + a * d1; 55 + d0 = d1; 56 + d1 = t; 57 + } 58 + *best_numerator = n1; 59 + *best_denominator = d1; 60 + } 61 + 62 + EXPORT_SYMBOL(rational_best_approximation);