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,