0001
0002 #ifndef _FIXP_ARITH_H
0003 #define _FIXP_ARITH_H
0004
0005 #include <linux/math64.h>
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/types.h>
0021
0022 static const s32 sin_table[] = {
0023 0x00000000, 0x023be165, 0x04779632, 0x06b2f1d2, 0x08edc7b6, 0x0b27eb5c,
0024 0x0d61304d, 0x0f996a26, 0x11d06c96, 0x14060b67, 0x163a1a7d, 0x186c6ddd,
0025 0x1a9cd9ac, 0x1ccb3236, 0x1ef74bf2, 0x2120fb82, 0x234815ba, 0x256c6f9e,
0026 0x278dde6e, 0x29ac379f, 0x2bc750e8, 0x2ddf003f, 0x2ff31bdd, 0x32037a44,
0027 0x340ff241, 0x36185aee, 0x381c8bb5, 0x3a1c5c56, 0x3c17a4e7, 0x3e0e3ddb,
0028 0x3fffffff, 0x41ecc483, 0x43d464fa, 0x45b6bb5d, 0x4793a20f, 0x496af3e1,
0029 0x4b3c8c11, 0x4d084650, 0x4ecdfec6, 0x508d9210, 0x5246dd48, 0x53f9be04,
0030 0x55a6125a, 0x574bb8e5, 0x58ea90c2, 0x5a827999, 0x5c135399, 0x5d9cff82,
0031 0x5f1f5ea0, 0x609a52d1, 0x620dbe8a, 0x637984d3, 0x64dd894f, 0x6639b039,
0032 0x678dde6d, 0x68d9f963, 0x6a1de735, 0x6b598ea1, 0x6c8cd70a, 0x6db7a879,
0033 0x6ed9eba0, 0x6ff389de, 0x71046d3c, 0x720c8074, 0x730baeec, 0x7401e4bf,
0034 0x74ef0ebb, 0x75d31a5f, 0x76adf5e5, 0x777f903b, 0x7847d908, 0x7906c0af,
0035 0x79bc384c, 0x7a6831b8, 0x7b0a9f8c, 0x7ba3751c, 0x7c32a67c, 0x7cb82884,
0036 0x7d33f0c8, 0x7da5f5a3, 0x7e0e2e31, 0x7e6c924f, 0x7ec11aa3, 0x7f0bc095,
0037 0x7f4c7e52, 0x7f834ecf, 0x7fb02dc4, 0x7fd317b3, 0x7fec09e1, 0x7ffb025e,
0038 0x7fffffff
0039 };
0040
0041
0042
0043
0044
0045
0046
0047
0048 static inline s32 __fixp_sin32(int degrees)
0049 {
0050 s32 ret;
0051 bool negative = false;
0052
0053 if (degrees > 180) {
0054 negative = true;
0055 degrees -= 180;
0056 }
0057 if (degrees > 90)
0058 degrees = 180 - degrees;
0059
0060 ret = sin_table[degrees];
0061
0062 return negative ? -ret : ret;
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072 static inline s32 fixp_sin32(int degrees)
0073 {
0074 degrees = (degrees % 360 + 360) % 360;
0075
0076 return __fixp_sin32(degrees);
0077 }
0078
0079
0080 #define fixp_cos32(v) fixp_sin32((v) + 90)
0081
0082
0083
0084
0085
0086
0087
0088 #define fixp_sin16(v) (fixp_sin32(v) >> 16)
0089 #define fixp_cos16(v) (fixp_cos32(v) >> 16)
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 static inline s32 fixp_sin32_rad(u32 radians, u32 twopi)
0113 {
0114 int degrees;
0115 s32 v1, v2, dx, dy;
0116 s64 tmp;
0117
0118
0119
0120
0121 BUG_ON(twopi > 1 << 18);
0122
0123 degrees = (radians * 360) / twopi;
0124 tmp = radians - (degrees * twopi) / 360;
0125
0126 degrees = (degrees % 360 + 360) % 360;
0127 v1 = __fixp_sin32(degrees);
0128
0129 v2 = fixp_sin32(degrees + 1);
0130
0131 dx = twopi / 360;
0132 dy = v2 - v1;
0133
0134 tmp *= dy;
0135
0136 return v1 + div_s64(tmp, dx);
0137 }
0138
0139
0140
0141 #define fixp_cos32_rad(rad, twopi) \
0142 fixp_sin32_rad(rad + twopi / 4, twopi)
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153 static inline int fixp_linear_interpolate(int x0, int y0, int x1, int y1, int x)
0154 {
0155 if (y0 == y1 || x == x0)
0156 return y0;
0157 if (x1 == x0 || x == x1)
0158 return y1;
0159
0160 return y0 + ((y1 - y0) * (x - x0) / (x1 - x0));
0161 }
0162
0163 #endif