1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * HID Sensors Driver 4 * Copyright (c) 2012, Intel Corporation. 5 */ 6 #include <linux/device.h> 7 #include <linux/platform_device.h> 8 #include <linux/module.h> 9 #include <linux/interrupt.h> 10 #include <linux/irq.h> 11 #include <linux/kernel.h> 12 #include <linux/slab.h> 13 #include <linux/time.h> 14 15 #include <linux/hid-sensor-hub.h> 16 #include <linux/iio/iio.h> 17 #include <linux/iio/sysfs.h> 18 19 #define HZ_PER_MHZ 1000000L 20 21 static struct { 22 u32 usage_id; 23 int unit; /* 0 for default others from HID sensor spec */ 24 int scale_val0; /* scale, whole number */ 25 int scale_val1; /* scale, fraction in nanos */ 26 } unit_conversion[] = { 27 {HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650000}, 28 {HID_USAGE_SENSOR_ACCEL_3D, 29 HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0}, 30 {HID_USAGE_SENSOR_ACCEL_3D, 31 HID_USAGE_SENSOR_UNITS_G, 9, 806650000}, 32 33 {HID_USAGE_SENSOR_GRAVITY_VECTOR, 0, 9, 806650000}, 34 {HID_USAGE_SENSOR_GRAVITY_VECTOR, 35 HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0}, 36 {HID_USAGE_SENSOR_GRAVITY_VECTOR, 37 HID_USAGE_SENSOR_UNITS_G, 9, 806650000}, 38 39 {HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453293}, 40 {HID_USAGE_SENSOR_GYRO_3D, 41 HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0}, 42 {HID_USAGE_SENSOR_GYRO_3D, 43 HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453293}, 44 45 {HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000000}, 46 {HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0}, 47 48 {HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453293}, 49 {HID_USAGE_SENSOR_INCLINOMETER_3D, 50 HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293}, 51 {HID_USAGE_SENSOR_INCLINOMETER_3D, 52 HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0}, 53 54 {HID_USAGE_SENSOR_ALS, 0, 1, 0}, 55 {HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0}, 56 57 {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, 58 {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000}, 59 60 {HID_USAGE_SENSOR_TIME_TIMESTAMP, 0, 1000000000, 0}, 61 {HID_USAGE_SENSOR_TIME_TIMESTAMP, HID_USAGE_SENSOR_UNITS_MILLISECOND, 62 1000000, 0}, 63 64 {HID_USAGE_SENSOR_DEVICE_ORIENTATION, 0, 1, 0}, 65 66 {HID_USAGE_SENSOR_RELATIVE_ORIENTATION, 0, 1, 0}, 67 68 {HID_USAGE_SENSOR_GEOMAGNETIC_ORIENTATION, 0, 1, 0}, 69 70 {HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0}, 71 {HID_USAGE_SENSOR_TEMPERATURE, HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0}, 72 73 {HID_USAGE_SENSOR_HUMIDITY, 0, 1000, 0}, 74 {HID_USAGE_SENSOR_HINGE, 0, 0, 17453293}, 75 {HID_USAGE_SENSOR_HINGE, HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293}, 76 }; 77 78 static void simple_div(int dividend, int divisor, int *whole, 79 int *micro_frac) 80 { 81 int rem; 82 int exp = 0; 83 84 *micro_frac = 0; 85 if (divisor == 0) { 86 *whole = 0; 87 return; 88 } 89 *whole = dividend/divisor; 90 rem = dividend % divisor; 91 if (rem) { 92 while (rem <= divisor) { 93 rem *= 10; 94 exp++; 95 } 96 *micro_frac = (rem / divisor) * int_pow(10, 6 - exp); 97 } 98 } 99 100 static void split_micro_fraction(unsigned int no, int exp, int *val1, int *val2) 101 { 102 int divisor = int_pow(10, exp); 103 104 *val1 = no / divisor; 105 *val2 = no % divisor * int_pow(10, 6 - exp); 106 } 107 108 /* 109 VTF format uses exponent and variable size format. 110 For example if the size is 2 bytes 111 0x0067 with VTF16E14 format -> +1.03 112 To convert just change to 0x67 to decimal and use two decimal as E14 stands 113 for 10^-2. 114 Negative numbers are 2's complement 115 */ 116 static void convert_from_vtf_format(u32 value, int size, int exp, 117 int *val1, int *val2) 118 { 119 int sign = 1; 120 121 if (value & BIT(size*8 - 1)) { 122 value = ((1LL << (size * 8)) - value); 123 sign = -1; 124 } 125 exp = hid_sensor_convert_exponent(exp); 126 if (exp >= 0) { 127 *val1 = sign * value * int_pow(10, exp); 128 *val2 = 0; 129 } else { 130 split_micro_fraction(value, -exp, val1, val2); 131 if (*val1) 132 *val1 = sign * (*val1); 133 else 134 *val2 = sign * (*val2); 135 } 136 } 137 138 static u32 convert_to_vtf_format(int size, int exp, int val1, int val2) 139 { 140 int divisor; 141 u32 value; 142 int sign = 1; 143 144 if (val1 < 0 || val2 < 0) 145 sign = -1; 146 exp = hid_sensor_convert_exponent(exp); 147 if (exp < 0) { 148 divisor = int_pow(10, 6 + exp); 149 value = abs(val1) * int_pow(10, -exp); 150 value += abs(val2) / divisor; 151 } else { 152 divisor = int_pow(10, exp); 153 value = abs(val1) / divisor; 154 } 155 if (sign < 0) 156 value = ((1LL << (size * 8)) - value); 157 158 return value; 159 } 160 161 s32 hid_sensor_read_poll_value(struct hid_sensor_common *st) 162 { 163 s32 value = 0; 164 int ret; 165 166 ret = sensor_hub_get_feature(st->hsdev, 167 st->poll.report_id, 168 st->poll.index, sizeof(value), &value); 169 170 if (ret < 0 || value < 0) { 171 return -EINVAL; 172 } else { 173 if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) 174 value = value * 1000; 175 } 176 177 return value; 178 } 179 EXPORT_SYMBOL(hid_sensor_read_poll_value); 180 181 int hid_sensor_read_samp_freq_value(struct hid_sensor_common *st, 182 int *val1, int *val2) 183 { 184 s32 value; 185 int ret; 186 187 ret = sensor_hub_get_feature(st->hsdev, 188 st->poll.report_id, 189 st->poll.index, sizeof(value), &value); 190 if (ret < 0 || value < 0) { 191 *val1 = *val2 = 0; 192 return -EINVAL; 193 } else { 194 if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) 195 simple_div(1000, value, val1, val2); 196 else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) 197 simple_div(1, value, val1, val2); 198 else { 199 *val1 = *val2 = 0; 200 return -EINVAL; 201 } 202 } 203 204 return IIO_VAL_INT_PLUS_MICRO; 205 } 206 EXPORT_SYMBOL(hid_sensor_read_samp_freq_value); 207 208 int hid_sensor_write_samp_freq_value(struct hid_sensor_common *st, 209 int val1, int val2) 210 { 211 s32 value; 212 int ret; 213 214 if (val1 < 0 || val2 < 0) 215 return -EINVAL; 216 217 value = val1 * HZ_PER_MHZ + val2; 218 if (value) { 219 if (st->poll.units == HID_USAGE_SENSOR_UNITS_MILLISECOND) 220 value = NSEC_PER_SEC / value; 221 else if (st->poll.units == HID_USAGE_SENSOR_UNITS_SECOND) 222 value = USEC_PER_SEC / value; 223 else 224 value = 0; 225 } 226 ret = sensor_hub_set_feature(st->hsdev, st->poll.report_id, 227 st->poll.index, sizeof(value), &value); 228 if (ret < 0 || value < 0) 229 return -EINVAL; 230 231 ret = sensor_hub_get_feature(st->hsdev, 232 st->poll.report_id, 233 st->poll.index, sizeof(value), &value); 234 if (ret < 0 || value < 0) 235 return -EINVAL; 236 237 st->poll_interval = value; 238 239 return 0; 240 } 241 EXPORT_SYMBOL(hid_sensor_write_samp_freq_value); 242 243 int hid_sensor_read_raw_hyst_value(struct hid_sensor_common *st, 244 int *val1, int *val2) 245 { 246 s32 value; 247 int ret; 248 249 ret = sensor_hub_get_feature(st->hsdev, 250 st->sensitivity.report_id, 251 st->sensitivity.index, sizeof(value), 252 &value); 253 if (ret < 0 || value < 0) { 254 *val1 = *val2 = 0; 255 return -EINVAL; 256 } else { 257 convert_from_vtf_format(value, st->sensitivity.size, 258 st->sensitivity.unit_expo, 259 val1, val2); 260 } 261 262 return IIO_VAL_INT_PLUS_MICRO; 263 } 264 EXPORT_SYMBOL(hid_sensor_read_raw_hyst_value); 265 266 int hid_sensor_read_raw_hyst_rel_value(struct hid_sensor_common *st, int *val1, 267 int *val2) 268 { 269 s32 value; 270 int ret; 271 272 ret = sensor_hub_get_feature(st->hsdev, 273 st->sensitivity_rel.report_id, 274 st->sensitivity_rel.index, sizeof(value), 275 &value); 276 if (ret < 0 || value < 0) { 277 *val1 = *val2 = 0; 278 return -EINVAL; 279 } 280 281 convert_from_vtf_format(value, st->sensitivity_rel.size, 282 st->sensitivity_rel.unit_expo, val1, val2); 283 284 return IIO_VAL_INT_PLUS_MICRO; 285 } 286 EXPORT_SYMBOL(hid_sensor_read_raw_hyst_rel_value); 287 288 289 int hid_sensor_write_raw_hyst_value(struct hid_sensor_common *st, 290 int val1, int val2) 291 { 292 s32 value; 293 int ret; 294 295 if (val1 < 0 || val2 < 0) 296 return -EINVAL; 297 298 value = convert_to_vtf_format(st->sensitivity.size, 299 st->sensitivity.unit_expo, 300 val1, val2); 301 ret = sensor_hub_set_feature(st->hsdev, st->sensitivity.report_id, 302 st->sensitivity.index, sizeof(value), 303 &value); 304 if (ret < 0 || value < 0) 305 return -EINVAL; 306 307 ret = sensor_hub_get_feature(st->hsdev, 308 st->sensitivity.report_id, 309 st->sensitivity.index, sizeof(value), 310 &value); 311 if (ret < 0 || value < 0) 312 return -EINVAL; 313 314 st->raw_hystersis = value; 315 316 return 0; 317 } 318 EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value); 319 320 int hid_sensor_write_raw_hyst_rel_value(struct hid_sensor_common *st, 321 int val1, int val2) 322 { 323 s32 value; 324 int ret; 325 326 if (val1 < 0 || val2 < 0) 327 return -EINVAL; 328 329 value = convert_to_vtf_format(st->sensitivity_rel.size, 330 st->sensitivity_rel.unit_expo, 331 val1, val2); 332 ret = sensor_hub_set_feature(st->hsdev, st->sensitivity_rel.report_id, 333 st->sensitivity_rel.index, sizeof(value), 334 &value); 335 if (ret < 0 || value < 0) 336 return -EINVAL; 337 338 ret = sensor_hub_get_feature(st->hsdev, 339 st->sensitivity_rel.report_id, 340 st->sensitivity_rel.index, sizeof(value), 341 &value); 342 if (ret < 0 || value < 0) 343 return -EINVAL; 344 345 st->raw_hystersis = value; 346 347 return 0; 348 } 349 EXPORT_SYMBOL(hid_sensor_write_raw_hyst_rel_value); 350 351 /* 352 * This fuction applies the unit exponent to the scale. 353 * For example: 354 * 9.806650000 ->exp:2-> val0[980]val1[665000000] 355 * 9.000806000 ->exp:2-> val0[900]val1[80600000] 356 * 0.174535293 ->exp:2-> val0[17]val1[453529300] 357 * 1.001745329 ->exp:0-> val0[1]val1[1745329] 358 * 1.001745329 ->exp:2-> val0[100]val1[174532900] 359 * 1.001745329 ->exp:4-> val0[10017]val1[453290000] 360 * 9.806650000 ->exp:-2-> val0[0]val1[98066500] 361 */ 362 static void adjust_exponent_nano(int *val0, int *val1, int scale0, 363 int scale1, int exp) 364 { 365 int divisor; 366 int i; 367 int x; 368 int res; 369 int rem; 370 371 if (exp > 0) { 372 *val0 = scale0 * int_pow(10, exp); 373 res = 0; 374 if (exp > 9) { 375 *val1 = 0; 376 return; 377 } 378 for (i = 0; i < exp; ++i) { 379 divisor = int_pow(10, 8 - i); 380 x = scale1 / divisor; 381 res += int_pow(10, exp - 1 - i) * x; 382 scale1 = scale1 % divisor; 383 } 384 *val0 += res; 385 *val1 = scale1 * int_pow(10, exp); 386 } else if (exp < 0) { 387 exp = abs(exp); 388 if (exp > 9) { 389 *val0 = *val1 = 0; 390 return; 391 } 392 divisor = int_pow(10, exp); 393 *val0 = scale0 / divisor; 394 rem = scale0 % divisor; 395 res = 0; 396 for (i = 0; i < (9 - exp); ++i) { 397 divisor = int_pow(10, 8 - i); 398 x = scale1 / divisor; 399 res += int_pow(10, 8 - exp - i) * x; 400 scale1 = scale1 % divisor; 401 } 402 *val1 = rem * int_pow(10, 9 - exp) + res; 403 } else { 404 *val0 = scale0; 405 *val1 = scale1; 406 } 407 } 408 409 int hid_sensor_format_scale(u32 usage_id, 410 struct hid_sensor_hub_attribute_info *attr_info, 411 int *val0, int *val1) 412 { 413 int i; 414 int exp; 415 416 *val0 = 1; 417 *val1 = 0; 418 419 for (i = 0; i < ARRAY_SIZE(unit_conversion); ++i) { 420 if (unit_conversion[i].usage_id == usage_id && 421 unit_conversion[i].unit == attr_info->units) { 422 exp = hid_sensor_convert_exponent( 423 attr_info->unit_expo); 424 adjust_exponent_nano(val0, val1, 425 unit_conversion[i].scale_val0, 426 unit_conversion[i].scale_val1, exp); 427 break; 428 } 429 } 430 431 return IIO_VAL_INT_PLUS_NANO; 432 } 433 EXPORT_SYMBOL(hid_sensor_format_scale); 434 435 int64_t hid_sensor_convert_timestamp(struct hid_sensor_common *st, 436 int64_t raw_value) 437 { 438 return st->timestamp_ns_scale * raw_value; 439 } 440 EXPORT_SYMBOL(hid_sensor_convert_timestamp); 441 442 static 443 int hid_sensor_get_reporting_interval(struct hid_sensor_hub_device *hsdev, 444 u32 usage_id, 445 struct hid_sensor_common *st) 446 { 447 sensor_hub_input_get_attribute_info(hsdev, 448 HID_FEATURE_REPORT, usage_id, 449 HID_USAGE_SENSOR_PROP_REPORT_INTERVAL, 450 &st->poll); 451 /* Default unit of measure is milliseconds */ 452 if (st->poll.units == 0) 453 st->poll.units = HID_USAGE_SENSOR_UNITS_MILLISECOND; 454 455 st->poll_interval = -1; 456 457 return 0; 458 459 } 460 461 static void hid_sensor_get_report_latency_info(struct hid_sensor_hub_device *hsdev, 462 u32 usage_id, 463 struct hid_sensor_common *st) 464 { 465 sensor_hub_input_get_attribute_info(hsdev, HID_FEATURE_REPORT, 466 usage_id, 467 HID_USAGE_SENSOR_PROP_REPORT_LATENCY, 468 &st->report_latency); 469 470 hid_dbg(hsdev->hdev, "Report latency attributes: %x:%x\n", 471 st->report_latency.index, st->report_latency.report_id); 472 } 473 474 int hid_sensor_get_report_latency(struct hid_sensor_common *st) 475 { 476 int ret; 477 int value; 478 479 ret = sensor_hub_get_feature(st->hsdev, st->report_latency.report_id, 480 st->report_latency.index, sizeof(value), 481 &value); 482 if (ret < 0) 483 return ret; 484 485 return value; 486 } 487 EXPORT_SYMBOL(hid_sensor_get_report_latency); 488 489 int hid_sensor_set_report_latency(struct hid_sensor_common *st, int latency_ms) 490 { 491 return sensor_hub_set_feature(st->hsdev, st->report_latency.report_id, 492 st->report_latency.index, 493 sizeof(latency_ms), &latency_ms); 494 } 495 EXPORT_SYMBOL(hid_sensor_set_report_latency); 496 497 bool hid_sensor_batch_mode_supported(struct hid_sensor_common *st) 498 { 499 return st->report_latency.index > 0 && st->report_latency.report_id > 0; 500 } 501 EXPORT_SYMBOL(hid_sensor_batch_mode_supported); 502 503 int hid_sensor_parse_common_attributes(struct hid_sensor_hub_device *hsdev, 504 u32 usage_id, 505 struct hid_sensor_common *st, 506 const u32 *sensitivity_addresses, 507 u32 sensitivity_addresses_len) 508 { 509 510 struct hid_sensor_hub_attribute_info timestamp; 511 s32 value; 512 int ret; 513 int i; 514 515 hid_sensor_get_reporting_interval(hsdev, usage_id, st); 516 517 sensor_hub_input_get_attribute_info(hsdev, 518 HID_FEATURE_REPORT, usage_id, 519 HID_USAGE_SENSOR_PROP_REPORT_STATE, 520 &st->report_state); 521 522 sensor_hub_input_get_attribute_info(hsdev, 523 HID_FEATURE_REPORT, usage_id, 524 HID_USAGE_SENSOR_PROY_POWER_STATE, 525 &st->power_state); 526 527 st->power_state.logical_minimum = 1; 528 st->report_state.logical_minimum = 1; 529 530 sensor_hub_input_get_attribute_info(hsdev, 531 HID_FEATURE_REPORT, usage_id, 532 HID_USAGE_SENSOR_PROP_SENSITIVITY_ABS, 533 &st->sensitivity); 534 535 sensor_hub_input_get_attribute_info(hsdev, 536 HID_FEATURE_REPORT, usage_id, 537 HID_USAGE_SENSOR_PROP_SENSITIVITY_REL_PCT, 538 &st->sensitivity_rel); 539 /* 540 * Set Sensitivity field ids, when there is no individual modifier, will 541 * check absolute sensitivity and relative sensitivity of data field 542 */ 543 for (i = 0; i < sensitivity_addresses_len; i++) { 544 if (st->sensitivity.index < 0) 545 sensor_hub_input_get_attribute_info( 546 hsdev, HID_FEATURE_REPORT, usage_id, 547 HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_ABS | 548 sensitivity_addresses[i], 549 &st->sensitivity); 550 551 if (st->sensitivity_rel.index < 0) 552 sensor_hub_input_get_attribute_info( 553 hsdev, HID_FEATURE_REPORT, usage_id, 554 HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVITY_REL_PCT | 555 sensitivity_addresses[i], 556 &st->sensitivity_rel); 557 } 558 559 st->raw_hystersis = -1; 560 561 sensor_hub_input_get_attribute_info(hsdev, 562 HID_INPUT_REPORT, usage_id, 563 HID_USAGE_SENSOR_TIME_TIMESTAMP, 564 ×tamp); 565 if (timestamp.index >= 0 && timestamp.report_id) { 566 int val0, val1; 567 568 hid_sensor_format_scale(HID_USAGE_SENSOR_TIME_TIMESTAMP, 569 ×tamp, &val0, &val1); 570 st->timestamp_ns_scale = val0; 571 } else 572 st->timestamp_ns_scale = 1000000000; 573 574 hid_sensor_get_report_latency_info(hsdev, usage_id, st); 575 576 hid_dbg(hsdev->hdev, "common attributes: %x:%x, %x:%x, %x:%x %x:%x %x:%x\n", 577 st->poll.index, st->poll.report_id, 578 st->report_state.index, st->report_state.report_id, 579 st->power_state.index, st->power_state.report_id, 580 st->sensitivity.index, st->sensitivity.report_id, 581 timestamp.index, timestamp.report_id); 582 583 ret = sensor_hub_get_feature(hsdev, 584 st->power_state.report_id, 585 st->power_state.index, sizeof(value), &value); 586 if (ret < 0) 587 return ret; 588 if (value < 0) 589 return -EINVAL; 590 591 return 0; 592 } 593 EXPORT_SYMBOL(hid_sensor_parse_common_attributes); 594 595 MODULE_AUTHOR("Srinivas Pandruvada <srinivas.pandruvada@intel.com>"); 596 MODULE_DESCRIPTION("HID Sensor common attribute processing"); 597 MODULE_LICENSE("GPL"); 598