| .. | .. |
|---|
| 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; |
|---|