d4ad4082c800807ee031d01885e3b2e394a90019
[linux-2.6-microblaze.git] / drivers / thermal / qcom / tsens-8916.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2015, The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/platform_device.h>
7 #include "tsens.h"
8
9 /* eeprom layout data for 8916 */
10 #define BASE0_MASK      0x0000007f
11 #define BASE1_MASK      0xfe000000
12 #define BASE0_SHIFT     0
13 #define BASE1_SHIFT     25
14
15 #define S0_P1_MASK      0x00000f80
16 #define S1_P1_MASK      0x003e0000
17 #define S2_P1_MASK      0xf8000000
18 #define S3_P1_MASK      0x000003e0
19 #define S4_P1_MASK      0x000f8000
20
21 #define S0_P2_MASK      0x0001f000
22 #define S1_P2_MASK      0x07c00000
23 #define S2_P2_MASK      0x0000001f
24 #define S3_P2_MASK      0x00007c00
25 #define S4_P2_MASK      0x01f00000
26
27 #define S0_P1_SHIFT     7
28 #define S1_P1_SHIFT     17
29 #define S2_P1_SHIFT     27
30 #define S3_P1_SHIFT     5
31 #define S4_P1_SHIFT     15
32
33 #define S0_P2_SHIFT     12
34 #define S1_P2_SHIFT     22
35 #define S2_P2_SHIFT     0
36 #define S3_P2_SHIFT     10
37 #define S4_P2_SHIFT     20
38
39 #define CAL_SEL_MASK    0xe0000000
40 #define CAL_SEL_SHIFT   29
41
42 static int calibrate_8916(struct tsens_priv *priv)
43 {
44         int base0 = 0, base1 = 0, i;
45         u32 p1[5], p2[5];
46         int mode = 0;
47         u32 *qfprom_cdata, *qfprom_csel;
48
49         qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
50         if (IS_ERR(qfprom_cdata))
51                 return PTR_ERR(qfprom_cdata);
52
53         qfprom_csel = (u32 *)qfprom_read(priv->dev, "calib_sel");
54         if (IS_ERR(qfprom_csel))
55                 return PTR_ERR(qfprom_csel);
56
57         mode = (qfprom_csel[0] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
58         dev_dbg(priv->dev, "calibration mode is %d\n", mode);
59
60         switch (mode) {
61         case TWO_PT_CALIB:
62                 base1 = (qfprom_cdata[1] & BASE1_MASK) >> BASE1_SHIFT;
63                 p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
64                 p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
65                 p2[2] = (qfprom_cdata[1] & S2_P2_MASK) >> S2_P2_SHIFT;
66                 p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
67                 p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
68                 for (i = 0; i < priv->num_sensors; i++)
69                         p2[i] = ((base1 + p2[i]) << 3);
70                 /* Fall through */
71         case ONE_PT_CALIB2:
72                 base0 = (qfprom_cdata[0] & BASE0_MASK);
73                 p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
74                 p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
75                 p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
76                 p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
77                 p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
78                 for (i = 0; i < priv->num_sensors; i++)
79                         p1[i] = (((base0) + p1[i]) << 3);
80                 break;
81         default:
82                 for (i = 0; i < priv->num_sensors; i++) {
83                         p1[i] = 500;
84                         p2[i] = 780;
85                 }
86                 break;
87         }
88
89         compute_intercept_slope(priv, p1, p2, mode);
90
91         return 0;
92 }
93
94 static const struct tsens_ops ops_8916 = {
95         .init           = init_common,
96         .calibrate      = calibrate_8916,
97         .get_temp       = get_temp_common,
98 };
99
100 const struct tsens_plat_data data_8916 = {
101         .num_sensors    = 5,
102         .ops            = &ops_8916,
103         .reg_offsets    = { [SROT_CTRL_OFFSET] = 0x0 },
104         .hw_ids         = (unsigned int []){0, 1, 2, 4, 5 },
105 };