Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: magnetometer: yas530: Add temperature calculation to "chip_info"

Add temperature calculation to the "chip_info" structure to ease the handling
of different YAS variants.

Signed-off-by: Jakob Hauser <jahau@rocketmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/1a8bffdb7e807455620a73f2d61981e7f9aab8d5.1660337264.git.jahau@rocketmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Jakob Hauser and committed by
Jonathan Cameron
2d6676ec 913fd409

+54 -69
+54 -69
drivers/iio/magnetometer/yamaha-yas530.c
··· 79 79 #define YAS530_DATA_BITS 12 80 80 #define YAS530_DATA_CENTER BIT(YAS530_DATA_BITS - 1) 81 81 #define YAS530_DATA_OVERFLOW (BIT(YAS530_DATA_BITS) - 1) 82 - #define YAS530_20DEGREES 182 /* Counts starting at -62 °C */ 83 82 84 83 #define YAS532_DEVICE_ID 0x02 /* YAS532/YAS533 (MS-3R/F) */ 85 84 #define YAS532_VERSION_AB 0 /* YAS532/533 AB (MS-3R/F AB) */ ··· 90 91 #define YAS532_DATA_BITS 13 91 92 #define YAS532_DATA_CENTER BIT(YAS532_DATA_BITS - 1) 92 93 #define YAS532_DATA_OVERFLOW (BIT(YAS532_DATA_BITS) - 1) 93 - #define YAS532_20DEGREES 390 /* Counts starting at -50 °C */ 94 94 95 95 /* Turn off device regulators etc after 5 seconds of inactivity */ 96 96 #define YAS5XX_AUTOSUSPEND_DELAY_MS 5000 ··· 129 131 * @volatile_reg: device-specific volatile registers 130 132 * @volatile_reg_qty: quantity of device-specific volatile registers 131 133 * @scaling_val2: scaling value for IIO_CHAN_INFO_SCALE 134 + * @t_ref: number of counts at reference temperature 20 °C 135 + * @min_temp_x10: starting point of temperature counting in 1/10:s degrees Celsius 136 + * 137 + * The "t_ref" value for YAS532/533 is known from the Android driver. 138 + * For YAS530 it was approximately measured. 139 + * 140 + * The temperatures "min_temp_x10" are derived from the temperature resolutions 141 + * given in the data sheets. 132 142 */ 133 143 struct yas5xx_chip_info { 134 144 unsigned int devid; ··· 145 139 const int *volatile_reg; 146 140 int volatile_reg_qty; 147 141 u32 scaling_val2; 142 + u16 t_ref; 143 + s16 min_temp_x10; 148 144 }; 149 145 150 146 /** ··· 345 337 (yas5xx->hard_offsets[axis] - c->r[axis]) * coef; 346 338 } 347 339 340 + static s32 yas5xx_calc_temperature(struct yas5xx *yas5xx, u16 t) 341 + { 342 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 343 + s32 to; 344 + u16 t_ref; 345 + s16 min_temp_x10; 346 + int ref_temp_x10; 347 + 348 + t_ref = ci->t_ref; 349 + min_temp_x10 = ci->min_temp_x10; 350 + ref_temp_x10 = 200; 351 + 352 + to = (min_temp_x10 + ((ref_temp_x10 - min_temp_x10) * t / t_ref)) * 100; 353 + return to; 354 + } 355 + 348 356 /** 349 357 * yas530_get_measure() - Measure a sample of all axis and process 350 358 * @yas5xx: The device state ··· 376 352 { 377 353 const struct yas5xx_chip_info *ci = yas5xx->chip_info; 378 354 struct yas5xx_calibration *c = &yas5xx->calibration; 379 - u16 t_ref, t, x, y1, y2; 355 + u16 t_ref, t_comp, t, x, y1, y2; 380 356 /* These are signed x, signed y1 etc */ 381 357 s32 sx, sy1, sy2, sy, sz; 382 358 int ret; ··· 391 367 sy1 = yas530_linearize(yas5xx, y1, 1); 392 368 sy2 = yas530_linearize(yas5xx, y2, 2); 393 369 394 - /* Set the temperature reference value (unit: counts) */ 395 - switch (ci->devid) { 396 - case YAS530_DEVICE_ID: 397 - t_ref = YAS530_20DEGREES; 398 - break; 399 - case YAS532_DEVICE_ID: 400 - t_ref = YAS532_20DEGREES; 401 - break; 402 - default: 403 - dev_err(yas5xx->dev, "unknown device type\n"); 404 - return -EINVAL; 405 - } 406 - 407 - /* Temperature compensation for x, y1, y2 respectively */ 370 + /* 371 + * Set the temperature for compensation (unit: counts): 372 + * YAS532/YAS533 version AC uses the temperature deviation as a 373 + * multiplier. YAS530 and YAS532 version AB use solely the t value. 374 + */ 375 + t_ref = ci->t_ref; 408 376 if (ci->devid == YAS532_DEVICE_ID && 409 377 yas5xx->version == YAS532_VERSION_AC) { 410 - /* 411 - * YAS532 version AC uses the temperature deviation as a 412 - * multiplier. 413 - * 414 - * Cx * (t - t_ref) 415 - * x' = x - ---------------- 416 - * 100 417 - */ 418 - sx = sx - (c->Cx * (t - t_ref)) / 100; 419 - sy1 = sy1 - (c->Cy1 * (t - t_ref)) / 100; 420 - sy2 = sy2 - (c->Cy2 * (t - t_ref)) / 100; 378 + t_comp = t - t_ref; 421 379 } else { 422 - /* 423 - * YAS530 and YAS532 version AB use solely the t value as a 424 - * multiplier. 425 - * 426 - * Cx * t 427 - * x' = x - ------ 428 - * 100 429 - */ 430 - sx = sx - (c->Cx * t) / 100; 431 - sy1 = sy1 - (c->Cy1 * t) / 100; 432 - sy2 = sy2 - (c->Cy2 * t) / 100; 380 + t_comp = t; 433 381 } 382 + 383 + /* 384 + * Temperature compensation for x, y1, y2 respectively: 385 + * 386 + * Cx * t_comp 387 + * x' = x - ----------- 388 + * 100 389 + */ 390 + sx = sx - (c->Cx * t_comp) / 100; 391 + sy1 = sy1 - (c->Cy1 * t_comp) / 100; 392 + sy2 = sy2 - (c->Cy2 * t_comp) / 100; 434 393 435 394 /* 436 395 * Break y1 and y2 into y and z, y1 and y2 are apparently encoding ··· 422 415 sy = sy1 - sy2; 423 416 sz = -sy1 - sy2; 424 417 425 - /* Process temperature readout */ 426 - switch (ci->devid) { 427 - case YAS530_DEVICE_ID: 428 - /* 429 - * Raw temperature value t is the number of counts starting 430 - * at -62 °C. Reference value t_ref is the number of counts 431 - * between -62 °C and 20 °C (82 °C range). 432 - * 433 - * Temperature in °C would be (82 / t_ref * t) - 62. 434 - * 435 - * Contrary to this, perform multiplication first and division 436 - * second due to calculating with integers. 437 - * 438 - * To get a nicer result, calculate with 1/10:s degrees Celsius 439 - * and finally multiply by 100 to return millidegrees Celsius. 440 - */ 441 - *to = ((820 * t / t_ref) - 620) * 100; 442 - break; 443 - case YAS532_DEVICE_ID: 444 - /* 445 - * Actually same procedure for YAS532 but the starting point is 446 - * at -50 °C. Reference value t_ref is the number of counts 447 - * between -50 °C and 20 °C (70 °C range). 448 - */ 449 - *to = ((700 * t / t_ref) - 500) * 100; 450 - break; 451 - default: 452 - dev_err(yas5xx->dev, "unknown device type\n"); 453 - return -EINVAL; 454 - } 418 + /* Calculate temperature readout */ 419 + *to = yas5xx_calc_temperature(yas5xx, t); 455 420 456 421 /* 457 422 * Calibrate [x,y,z] with some formulas like this: ··· 914 935 .volatile_reg = yas530_volatile_reg, 915 936 .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), 916 937 .scaling_val2 = 100000000, /* picotesla to Gauss */ 938 + .t_ref = 182, /* counts */ 939 + .min_temp_x10 = -620, /* 1/10:s degrees Celsius */ 917 940 }, 918 941 [yas532] = { 919 942 .devid = YAS532_DEVICE_ID, ··· 924 943 .volatile_reg = yas530_volatile_reg, 925 944 .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), 926 945 .scaling_val2 = 100000, /* nanotesla to Gauss */ 946 + .t_ref = 390, /* counts */ 947 + .min_temp_x10 = -500, /* 1/10:s degrees Celsius */ 927 948 }, 928 949 [yas533] = { 929 950 .devid = YAS532_DEVICE_ID, ··· 934 951 .volatile_reg = yas530_volatile_reg, 935 952 .volatile_reg_qty = ARRAY_SIZE(yas530_volatile_reg), 936 953 .scaling_val2 = 100000, /* nanotesla to Gauss */ 954 + .t_ref = 390, /* counts */ 955 + .min_temp_x10 = -500, /* 1/10:s degrees Celsius */ 937 956 }, 938 957 }; 939 958