blob: 44da02f594ac04edfe6f8096f8dcc0756a11ce54 [file] [log] [blame]
Andrew Scullb4b6d4a2019-01-02 15:54:55 +00001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2018, Linaro Limited
5 */
6
7#include <linux/regmap.h>
8#include <linux/bitops.h>
9#include "tsens.h"
10
11#define STATUS_OFFSET 0xa0
12#define LAST_TEMP_MASK 0xfff
13#define STATUS_VALID_BIT BIT(21)
14
15static int get_temp_tsens_v2(struct tsens_device *tmdev, int id, int *temp)
16{
17 struct tsens_sensor *s = &tmdev->sensor[id];
18 u32 code;
19 unsigned int status_reg;
20 u32 last_temp = 0, last_temp2 = 0, last_temp3 = 0;
21 int ret;
22
23 status_reg = tmdev->tm_offset + STATUS_OFFSET + s->hw_id * 4;
24 ret = regmap_read(tmdev->map, status_reg, &code);
25 if (ret)
26 return ret;
27 last_temp = code & LAST_TEMP_MASK;
28 if (code & STATUS_VALID_BIT)
29 goto done;
30
31 /* Try a second time */
32 ret = regmap_read(tmdev->map, status_reg, &code);
33 if (ret)
34 return ret;
35 if (code & STATUS_VALID_BIT) {
36 last_temp = code & LAST_TEMP_MASK;
37 goto done;
38 } else {
39 last_temp2 = code & LAST_TEMP_MASK;
40 }
41
42 /* Try a third/last time */
43 ret = regmap_read(tmdev->map, status_reg, &code);
44 if (ret)
45 return ret;
46 if (code & STATUS_VALID_BIT) {
47 last_temp = code & LAST_TEMP_MASK;
48 goto done;
49 } else {
50 last_temp3 = code & LAST_TEMP_MASK;
51 }
52
53 if (last_temp == last_temp2)
54 last_temp = last_temp2;
55 else if (last_temp2 == last_temp3)
56 last_temp = last_temp3;
57done:
58 /* Convert temperature from deciCelsius to milliCelsius */
59 *temp = sign_extend32(last_temp, fls(LAST_TEMP_MASK) - 1) * 100;
60
61 return 0;
62}
63
64static const struct tsens_ops ops_generic_v2 = {
65 .init = init_common,
66 .get_temp = get_temp_tsens_v2,
67};
68
69const struct tsens_data data_tsens_v2 = {
70 .ops = &ops_generic_v2,
71};
72
73/* Kept around for backward compatibility with old msm8996.dtsi */
74const struct tsens_data data_8996 = {
75 .num_sensors = 13,
76 .ops = &ops_generic_v2,
77};