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