fixedpoint.h 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #ifdef _FIXP_ARITH_H
  7. #error "This implementation is meant to override fixp-arith.h, don't use both"
  8. #endif
  9. #ifndef _FIXEDPOINT_H_
  10. #define _FIXEDPOINT_H_
  11. #include <linux/types.h>
  12. #include <linux/bits.h>
  13. /*
  14. * Normally would typedef'ed, but checkpatch doesn't like typedef.
  15. * Also should be normally typedef'ed to intmax_t but that doesn't seem to be
  16. * available in the kernel
  17. */
  18. #define fp_t size_t
  19. /* (Arbitrarily) make the first 25% of the bits to be the fractional bits */
  20. #define FP_FRACTIONAL_BITS ((sizeof(fp_t) * 8) / 4)
  21. #define FP(__i, __f_n, __f_d) \
  22. ((((fp_t)(__i)) << FP_FRACTIONAL_BITS) + \
  23. (((__f_n) << FP_FRACTIONAL_BITS) / (__f_d)))
  24. #define FP_INT(__i) FP(__i, 0, 1)
  25. #define FP_ONE FP_INT(1)
  26. #define FP_ZERO FP_INT(0)
  27. static inline size_t fp_frac_base(void)
  28. {
  29. return GENMASK(FP_FRACTIONAL_BITS - 1, 0);
  30. }
  31. static inline size_t fp_frac(fp_t a)
  32. {
  33. return a & GENMASK(FP_FRACTIONAL_BITS - 1, 0);
  34. }
  35. static inline size_t fp_int(fp_t a)
  36. {
  37. return a >> FP_FRACTIONAL_BITS;
  38. }
  39. static inline size_t fp_round(fp_t a)
  40. {
  41. /* is the fractional part >= frac_max / 2? */
  42. bool round_up = fp_frac(a) >= fp_frac_base() / 2;
  43. return fp_int(a) + round_up;
  44. }
  45. static inline fp_t fp_mult(fp_t a, fp_t b)
  46. {
  47. return (a * b) >> FP_FRACTIONAL_BITS;
  48. }
  49. static inline fp_t fp_div(fp_t a, fp_t b)
  50. {
  51. return (a << FP_FRACTIONAL_BITS) / b;
  52. }
  53. #endif