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