.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * HID Sensors Driver |
---|
3 | 4 | * Copyright (c) 2012, Intel Corporation. |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms and conditions of the GNU General Public License, |
---|
7 | | - * version 2, as published by the Free Software Foundation. |
---|
8 | | - * |
---|
9 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
10 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
11 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
12 | | - * more details. |
---|
13 | | - * |
---|
14 | | - * You should have received a copy of the GNU General Public License along with |
---|
15 | | - * this program; if not, write to the Free Software Foundation, Inc., |
---|
16 | | - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
---|
17 | | - * |
---|
18 | 5 | */ |
---|
19 | 6 | #include <linux/device.h> |
---|
20 | 7 | #include <linux/platform_device.h> |
---|
21 | 8 | #include <linux/module.h> |
---|
22 | 9 | #include <linux/interrupt.h> |
---|
23 | 10 | #include <linux/irq.h> |
---|
| 11 | +#include <linux/kernel.h> |
---|
24 | 12 | #include <linux/slab.h> |
---|
| 13 | +#include <linux/time.h> |
---|
| 14 | + |
---|
25 | 15 | #include <linux/hid-sensor-hub.h> |
---|
26 | 16 | #include <linux/iio/iio.h> |
---|
27 | 17 | #include <linux/iio/sysfs.h> |
---|
| 18 | + |
---|
| 19 | +#define HZ_PER_MHZ 1000000L |
---|
28 | 20 | |
---|
29 | 21 | static struct { |
---|
30 | 22 | u32 usage_id; |
---|
.. | .. |
---|
81 | 73 | {HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0}, |
---|
82 | 74 | }; |
---|
83 | 75 | |
---|
84 | | -static int pow_10(unsigned power) |
---|
85 | | -{ |
---|
86 | | - int i; |
---|
87 | | - int ret = 1; |
---|
88 | | - for (i = 0; i < power; ++i) |
---|
89 | | - ret = ret * 10; |
---|
90 | | - |
---|
91 | | - return ret; |
---|
92 | | -} |
---|
93 | | - |
---|
94 | 76 | static void simple_div(int dividend, int divisor, int *whole, |
---|
95 | 77 | int *micro_frac) |
---|
96 | 78 | { |
---|
.. | .. |
---|
109 | 91 | rem *= 10; |
---|
110 | 92 | exp++; |
---|
111 | 93 | } |
---|
112 | | - *micro_frac = (rem / divisor) * pow_10(6-exp); |
---|
| 94 | + *micro_frac = (rem / divisor) * int_pow(10, 6 - exp); |
---|
113 | 95 | } |
---|
114 | 96 | } |
---|
115 | 97 | |
---|
116 | 98 | static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2) |
---|
117 | 99 | { |
---|
118 | | - *val1 = no/pow_10(exp); |
---|
119 | | - *val2 = no%pow_10(exp) * pow_10(6-exp); |
---|
| 100 | + int divisor = int_pow(10, exp); |
---|
| 101 | + |
---|
| 102 | + *val1 = no / divisor; |
---|
| 103 | + *val2 = no % divisor * int_pow(10, 6 - exp); |
---|
120 | 104 | } |
---|
121 | 105 | |
---|
122 | 106 | /* |
---|
.. | .. |
---|
138 | 122 | } |
---|
139 | 123 | exp = hid_sensor_convert_exponent(exp); |
---|
140 | 124 | if (exp >= 0) { |
---|
141 | | - *val1 = sign * value * pow_10(exp); |
---|
| 125 | + *val1 = sign * value * int_pow(10, exp); |
---|
142 | 126 | *val2 = 0; |
---|
143 | 127 | } else { |
---|
144 | 128 | split_micro_fraction(value, -exp, val1, val2); |
---|
.. | .. |
---|
151 | 135 | |
---|
152 | 136 | static u32 convert_to_vtf_format(int size, int exp, int val1, int val2) |
---|
153 | 137 | { |
---|
| 138 | + int divisor; |
---|
154 | 139 | u32 value; |
---|
155 | 140 | int sign = 1; |
---|
156 | 141 | |
---|
.. | .. |
---|
158 | 143 | sign = -1; |
---|
159 | 144 | exp = hid_sensor_convert_exponent(exp); |
---|
160 | 145 | if (exp < 0) { |
---|
161 | | - value = abs(val1) * pow_10(-exp); |
---|
162 | | - value += abs(val2) / pow_10(6+exp); |
---|
163 | | - } else |
---|
164 | | - value = abs(val1) / pow_10(exp); |
---|
| 146 | + divisor = int_pow(10, 6 + exp); |
---|
| 147 | + value = abs(val1) * int_pow(10, -exp); |
---|
| 148 | + value += abs(val2) / divisor; |
---|
| 149 | + } else { |
---|
| 150 | + divisor = int_pow(10, exp); |
---|
| 151 | + value = abs(val1) / divisor; |
---|
| 152 | + } |
---|
165 | 153 | if (sign < 0) |
---|
166 | 154 | value = ((1LL << (size * 8)) - value); |
---|
167 | 155 | |
---|
.. | .. |
---|
224 | 212 | if (val1 < 0 || val2 < 0) |
---|
225 | 213 | return -EINVAL; |
---|
226 | 214 | |
---|
227 | | - value = val1 * pow_10(6) + val2; |
---|
| 215 | + value = val1 * HZ_PER_MHZ + val2; |
---|
228 | 216 | if (value) { |
---|
229 | 217 | if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) |
---|
230 | | - value = pow_10(9)/value; |
---|
| 218 | + value = NSEC_PER_SEC / value; |
---|
231 | 219 | else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) |
---|
232 | | - value = pow_10(6)/value; |
---|
| 220 | + value = USEC_PER_SEC / value; |
---|
233 | 221 | else |
---|
234 | 222 | value = 0; |
---|
235 | 223 | } |
---|
.. | .. |
---|
318 | 306 | static void adjust_exponent_nano(int *val0, int *val1, int scale0, |
---|
319 | 307 | int scale1, int exp) |
---|
320 | 308 | { |
---|
| 309 | + int divisor; |
---|
321 | 310 | int i; |
---|
322 | 311 | int x; |
---|
323 | 312 | int res; |
---|
324 | 313 | int rem; |
---|
325 | 314 | |
---|
326 | 315 | if (exp > 0) { |
---|
327 | | - *val0 = scale0 * pow_10(exp); |
---|
| 316 | + *val0 = scale0 * int_pow(10, exp); |
---|
328 | 317 | res = 0; |
---|
329 | 318 | if (exp > 9) { |
---|
330 | 319 | *val1 = 0; |
---|
331 | 320 | return; |
---|
332 | 321 | } |
---|
333 | 322 | for (i = 0; i < exp; ++i) { |
---|
334 | | - x = scale1 / pow_10(8 - i); |
---|
335 | | - res += (pow_10(exp - 1 - i) * x); |
---|
336 | | - scale1 = scale1 % pow_10(8 - i); |
---|
| 323 | + divisor = int_pow(10, 8 - i); |
---|
| 324 | + x = scale1 / divisor; |
---|
| 325 | + res += int_pow(10, exp - 1 - i) * x; |
---|
| 326 | + scale1 = scale1 % divisor; |
---|
337 | 327 | } |
---|
338 | 328 | *val0 += res; |
---|
339 | | - *val1 = scale1 * pow_10(exp); |
---|
| 329 | + *val1 = scale1 * int_pow(10, exp); |
---|
340 | 330 | } else if (exp < 0) { |
---|
341 | 331 | exp = abs(exp); |
---|
342 | 332 | if (exp > 9) { |
---|
343 | 333 | *val0 = *val1 = 0; |
---|
344 | 334 | return; |
---|
345 | 335 | } |
---|
346 | | - *val0 = scale0 / pow_10(exp); |
---|
347 | | - rem = scale0 % pow_10(exp); |
---|
| 336 | + divisor = int_pow(10, exp); |
---|
| 337 | + *val0 = scale0 / divisor; |
---|
| 338 | + rem = scale0 % divisor; |
---|
348 | 339 | res = 0; |
---|
349 | 340 | for (i = 0; i < (9 - exp); ++i) { |
---|
350 | | - x = scale1 / pow_10(8 - i); |
---|
351 | | - res += (pow_10(8 - exp - i) * x); |
---|
352 | | - scale1 = scale1 % pow_10(8 - i); |
---|
| 341 | + divisor = int_pow(10, 8 - i); |
---|
| 342 | + x = scale1 / divisor; |
---|
| 343 | + res += int_pow(10, 8 - exp - i) * x; |
---|
| 344 | + scale1 = scale1 % divisor; |
---|
353 | 345 | } |
---|
354 | | - *val1 = rem * pow_10(9 - exp) + res; |
---|
| 346 | + *val1 = rem * int_pow(10, 9 - exp) + res; |
---|
355 | 347 | } else { |
---|
356 | 348 | *val0 = scale0; |
---|
357 | 349 | *val1 = scale1; |
---|