2 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <linux/platform_device.h>
16 #include <linux/regmap.h>
19 #define STATUS_OFFSET 0x10a0
20 #define LAST_TEMP_MASK 0xfff
21 #define STATUS_VALID_BIT BIT(21)
22 #define CODE_SIGN_BIT BIT(11)
24 static int get_temp_8996(struct tsens_device
*tmdev
, int id
, int *temp
)
26 struct tsens_sensor
*s
= &tmdev
->sensor
[id
];
28 unsigned int sensor_addr
;
29 int last_temp
= 0, last_temp2
= 0, last_temp3
= 0, ret
;
31 sensor_addr
= STATUS_OFFSET
+ s
->hw_id
* 4;
32 ret
= regmap_read(tmdev
->map
, sensor_addr
, &code
);
35 last_temp
= code
& LAST_TEMP_MASK
;
36 if (code
& STATUS_VALID_BIT
)
39 /* Try a second time */
40 ret
= regmap_read(tmdev
->map
, sensor_addr
, &code
);
43 if (code
& STATUS_VALID_BIT
) {
44 last_temp
= code
& LAST_TEMP_MASK
;
47 last_temp2
= code
& LAST_TEMP_MASK
;
50 /* Try a third/last time */
51 ret
= regmap_read(tmdev
->map
, sensor_addr
, &code
);
54 if (code
& STATUS_VALID_BIT
) {
55 last_temp
= code
& LAST_TEMP_MASK
;
58 last_temp3
= code
& LAST_TEMP_MASK
;
61 if (last_temp
== last_temp2
)
62 last_temp
= last_temp2
;
63 else if (last_temp2
== last_temp3
)
64 last_temp
= last_temp3
;
66 /* Code sign bit is the sign extension for a negative value */
67 if (last_temp
& CODE_SIGN_BIT
)
68 last_temp
|= ~CODE_SIGN_BIT
;
70 /* Temperatures are in deciCelicius */
71 *temp
= last_temp
* 100;
76 static const struct tsens_ops ops_8996
= {
78 .get_temp
= get_temp_8996
,
81 const struct tsens_data data_8996
= {