1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2018, Linaro Limited
7 #include <linux/regmap.h>
8 #include <linux/bitops.h>
11 #define STATUS_OFFSET 0xa0
12 #define LAST_TEMP_MASK 0xfff
13 #define STATUS_VALID_BIT BIT(21)
15 static int get_temp_tsens_v2(struct tsens_device
*tmdev
, int id
, int *temp
)
17 struct tsens_sensor
*s
= &tmdev
->sensor
[id
];
19 unsigned int status_reg
;
20 u32 last_temp
= 0, last_temp2
= 0, last_temp3
= 0;
23 status_reg
= tmdev
->tm_offset
+ STATUS_OFFSET
+ s
->hw_id
* 4;
24 ret
= regmap_read(tmdev
->map
, status_reg
, &code
);
27 last_temp
= code
& LAST_TEMP_MASK
;
28 if (code
& STATUS_VALID_BIT
)
31 /* Try a second time */
32 ret
= regmap_read(tmdev
->map
, status_reg
, &code
);
35 if (code
& STATUS_VALID_BIT
) {
36 last_temp
= code
& LAST_TEMP_MASK
;
39 last_temp2
= code
& LAST_TEMP_MASK
;
42 /* Try a third/last time */
43 ret
= regmap_read(tmdev
->map
, status_reg
, &code
);
46 if (code
& STATUS_VALID_BIT
) {
47 last_temp
= code
& LAST_TEMP_MASK
;
50 last_temp3
= code
& LAST_TEMP_MASK
;
53 if (last_temp
== last_temp2
)
54 last_temp
= last_temp2
;
55 else if (last_temp2
== last_temp3
)
56 last_temp
= last_temp3
;
58 /* Convert temperature from deciCelsius to milliCelsius */
59 *temp
= sign_extend32(last_temp
, fls(LAST_TEMP_MASK
) - 1) * 100;
64 static const struct tsens_ops ops_generic_v2
= {
66 .get_temp
= get_temp_tsens_v2
,
69 const struct tsens_data data_tsens_v2
= {
70 .ops
= &ops_generic_v2
,
73 /* Kept around for backward compatibility with old msm8996.dtsi */
74 const struct tsens_data data_8996
= {
76 .ops
= &ops_generic_v2
,