0001
0002
0003
0004
0005
0006 #include <linux/bitops.h>
0007 #include <linux/regmap.h>
0008 #include <linux/delay.h>
0009 #include <linux/slab.h>
0010 #include "tsens.h"
0011
0012
0013 #define SROT_HW_VER_OFF 0x0000
0014 #define SROT_CTRL_OFF 0x0004
0015
0016
0017 #define TM_INT_EN_OFF 0x0000
0018 #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF 0x0004
0019 #define TM_Sn_STATUS_OFF 0x0044
0020 #define TM_TRDY_OFF 0x0084
0021 #define TM_HIGH_LOW_INT_STATUS_OFF 0x0088
0022 #define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF 0x0090
0023
0024
0025 #define MSM8976_BASE0_MASK 0xff
0026 #define MSM8976_BASE1_MASK 0xff
0027 #define MSM8976_BASE1_SHIFT 8
0028
0029 #define MSM8976_S0_P1_MASK 0x3f00
0030 #define MSM8976_S1_P1_MASK 0x3f00000
0031 #define MSM8976_S2_P1_MASK 0x3f
0032 #define MSM8976_S3_P1_MASK 0x3f000
0033 #define MSM8976_S4_P1_MASK 0x3f00
0034 #define MSM8976_S5_P1_MASK 0x3f00000
0035 #define MSM8976_S6_P1_MASK 0x3f
0036 #define MSM8976_S7_P1_MASK 0x3f000
0037 #define MSM8976_S8_P1_MASK 0x1f8
0038 #define MSM8976_S9_P1_MASK 0x1f8000
0039 #define MSM8976_S10_P1_MASK 0xf8000000
0040 #define MSM8976_S10_P1_MASK_1 0x1
0041
0042 #define MSM8976_S0_P2_MASK 0xfc000
0043 #define MSM8976_S1_P2_MASK 0xfc000000
0044 #define MSM8976_S2_P2_MASK 0xfc0
0045 #define MSM8976_S3_P2_MASK 0xfc0000
0046 #define MSM8976_S4_P2_MASK 0xfc000
0047 #define MSM8976_S5_P2_MASK 0xfc000000
0048 #define MSM8976_S6_P2_MASK 0xfc0
0049 #define MSM8976_S7_P2_MASK 0xfc0000
0050 #define MSM8976_S8_P2_MASK 0x7e00
0051 #define MSM8976_S9_P2_MASK 0x7e00000
0052 #define MSM8976_S10_P2_MASK 0x7e
0053
0054 #define MSM8976_S0_P1_SHIFT 8
0055 #define MSM8976_S1_P1_SHIFT 20
0056 #define MSM8976_S2_P1_SHIFT 0
0057 #define MSM8976_S3_P1_SHIFT 12
0058 #define MSM8976_S4_P1_SHIFT 8
0059 #define MSM8976_S5_P1_SHIFT 20
0060 #define MSM8976_S6_P1_SHIFT 0
0061 #define MSM8976_S7_P1_SHIFT 12
0062 #define MSM8976_S8_P1_SHIFT 3
0063 #define MSM8976_S9_P1_SHIFT 15
0064 #define MSM8976_S10_P1_SHIFT 27
0065 #define MSM8976_S10_P1_SHIFT_1 0
0066
0067 #define MSM8976_S0_P2_SHIFT 14
0068 #define MSM8976_S1_P2_SHIFT 26
0069 #define MSM8976_S2_P2_SHIFT 6
0070 #define MSM8976_S3_P2_SHIFT 18
0071 #define MSM8976_S4_P2_SHIFT 14
0072 #define MSM8976_S5_P2_SHIFT 26
0073 #define MSM8976_S6_P2_SHIFT 6
0074 #define MSM8976_S7_P2_SHIFT 18
0075 #define MSM8976_S8_P2_SHIFT 9
0076 #define MSM8976_S9_P2_SHIFT 21
0077 #define MSM8976_S10_P2_SHIFT 1
0078
0079 #define MSM8976_CAL_SEL_MASK 0x3
0080
0081 #define MSM8976_CAL_DEGC_PT1 30
0082 #define MSM8976_CAL_DEGC_PT2 120
0083 #define MSM8976_SLOPE_FACTOR 1000
0084 #define MSM8976_SLOPE_DEFAULT 3200
0085
0086
0087 #define BASE0_MASK 0x000007f8
0088 #define BASE1_MASK 0x0007f800
0089 #define BASE0_SHIFT 3
0090 #define BASE1_SHIFT 11
0091
0092 #define S0_P1_MASK 0x0000003f
0093 #define S1_P1_MASK 0x0003f000
0094 #define S2_P1_MASK 0x3f000000
0095 #define S3_P1_MASK 0x000003f0
0096 #define S4_P1_MASK 0x003f0000
0097 #define S5_P1_MASK 0x0000003f
0098 #define S6_P1_MASK 0x0003f000
0099 #define S7_P1_MASK 0x3f000000
0100 #define S8_P1_MASK 0x000003f0
0101 #define S9_P1_MASK 0x003f0000
0102
0103 #define S0_P2_MASK 0x00000fc0
0104 #define S1_P2_MASK 0x00fc0000
0105 #define S2_P2_MASK_1_0 0xc0000000
0106 #define S2_P2_MASK_5_2 0x0000000f
0107 #define S3_P2_MASK 0x0000fc00
0108 #define S4_P2_MASK 0x0fc00000
0109 #define S5_P2_MASK 0x00000fc0
0110 #define S6_P2_MASK 0x00fc0000
0111 #define S7_P2_MASK_1_0 0xc0000000
0112 #define S7_P2_MASK_5_2 0x0000000f
0113 #define S8_P2_MASK 0x0000fc00
0114 #define S9_P2_MASK 0x0fc00000
0115
0116 #define S0_P1_SHIFT 0
0117 #define S0_P2_SHIFT 6
0118 #define S1_P1_SHIFT 12
0119 #define S1_P2_SHIFT 18
0120 #define S2_P1_SHIFT 24
0121 #define S2_P2_SHIFT_1_0 30
0122
0123 #define S2_P2_SHIFT_5_2 0
0124 #define S3_P1_SHIFT 4
0125 #define S3_P2_SHIFT 10
0126 #define S4_P1_SHIFT 16
0127 #define S4_P2_SHIFT 22
0128
0129 #define S5_P1_SHIFT 0
0130 #define S5_P2_SHIFT 6
0131 #define S6_P1_SHIFT 12
0132 #define S6_P2_SHIFT 18
0133 #define S7_P1_SHIFT 24
0134 #define S7_P2_SHIFT_1_0 30
0135
0136 #define S7_P2_SHIFT_5_2 0
0137 #define S8_P1_SHIFT 4
0138 #define S8_P2_SHIFT 10
0139 #define S9_P1_SHIFT 16
0140 #define S9_P2_SHIFT 22
0141
0142 #define CAL_SEL_MASK 7
0143 #define CAL_SEL_SHIFT 0
0144
0145 static void compute_intercept_slope_8976(struct tsens_priv *priv,
0146 u32 *p1, u32 *p2, u32 mode)
0147 {
0148 int i;
0149
0150 priv->sensor[0].slope = 3313;
0151 priv->sensor[1].slope = 3275;
0152 priv->sensor[2].slope = 3320;
0153 priv->sensor[3].slope = 3246;
0154 priv->sensor[4].slope = 3279;
0155 priv->sensor[5].slope = 3257;
0156 priv->sensor[6].slope = 3234;
0157 priv->sensor[7].slope = 3269;
0158 priv->sensor[8].slope = 3255;
0159 priv->sensor[9].slope = 3239;
0160 priv->sensor[10].slope = 3286;
0161
0162 for (i = 0; i < priv->num_sensors; i++) {
0163 priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
0164 (MSM8976_CAL_DEGC_PT1 *
0165 priv->sensor[i].slope);
0166 }
0167 }
0168
0169 static int calibrate_v1(struct tsens_priv *priv)
0170 {
0171 u32 base0 = 0, base1 = 0;
0172 u32 p1[10], p2[10];
0173 u32 mode = 0, lsb = 0, msb = 0;
0174 u32 *qfprom_cdata;
0175 int i;
0176
0177 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
0178 if (IS_ERR(qfprom_cdata))
0179 return PTR_ERR(qfprom_cdata);
0180
0181 mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
0182 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
0183
0184 switch (mode) {
0185 case TWO_PT_CALIB:
0186 base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
0187 p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
0188 p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
0189
0190 lsb = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
0191 msb = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
0192 p2[2] = msb << 2 | lsb;
0193 p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
0194 p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
0195 p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
0196 p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
0197
0198 lsb = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
0199 msb = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
0200 p2[7] = msb << 2 | lsb;
0201 p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
0202 p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
0203 for (i = 0; i < priv->num_sensors; i++)
0204 p2[i] = ((base1 + p2[i]) << 2);
0205 fallthrough;
0206 case ONE_PT_CALIB2:
0207 base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
0208 p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
0209 p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
0210 p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
0211 p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
0212 p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
0213 p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
0214 p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
0215 p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
0216 p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
0217 p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
0218 for (i = 0; i < priv->num_sensors; i++)
0219 p1[i] = (((base0) + p1[i]) << 2);
0220 break;
0221 default:
0222 for (i = 0; i < priv->num_sensors; i++) {
0223 p1[i] = 500;
0224 p2[i] = 780;
0225 }
0226 break;
0227 }
0228
0229 compute_intercept_slope(priv, p1, p2, mode);
0230 kfree(qfprom_cdata);
0231
0232 return 0;
0233 }
0234
0235 static int calibrate_8976(struct tsens_priv *priv)
0236 {
0237 int base0 = 0, base1 = 0, i;
0238 u32 p1[11], p2[11];
0239 int mode = 0, tmp = 0;
0240 u32 *qfprom_cdata;
0241
0242 qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
0243 if (IS_ERR(qfprom_cdata))
0244 return PTR_ERR(qfprom_cdata);
0245
0246 mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
0247 dev_dbg(priv->dev, "calibration mode is %d\n", mode);
0248
0249 switch (mode) {
0250 case TWO_PT_CALIB:
0251 base1 = (qfprom_cdata[2] & MSM8976_BASE1_MASK) >> MSM8976_BASE1_SHIFT;
0252 p2[0] = (qfprom_cdata[0] & MSM8976_S0_P2_MASK) >> MSM8976_S0_P2_SHIFT;
0253 p2[1] = (qfprom_cdata[0] & MSM8976_S1_P2_MASK) >> MSM8976_S1_P2_SHIFT;
0254 p2[2] = (qfprom_cdata[1] & MSM8976_S2_P2_MASK) >> MSM8976_S2_P2_SHIFT;
0255 p2[3] = (qfprom_cdata[1] & MSM8976_S3_P2_MASK) >> MSM8976_S3_P2_SHIFT;
0256 p2[4] = (qfprom_cdata[2] & MSM8976_S4_P2_MASK) >> MSM8976_S4_P2_SHIFT;
0257 p2[5] = (qfprom_cdata[2] & MSM8976_S5_P2_MASK) >> MSM8976_S5_P2_SHIFT;
0258 p2[6] = (qfprom_cdata[3] & MSM8976_S6_P2_MASK) >> MSM8976_S6_P2_SHIFT;
0259 p2[7] = (qfprom_cdata[3] & MSM8976_S7_P2_MASK) >> MSM8976_S7_P2_SHIFT;
0260 p2[8] = (qfprom_cdata[4] & MSM8976_S8_P2_MASK) >> MSM8976_S8_P2_SHIFT;
0261 p2[9] = (qfprom_cdata[4] & MSM8976_S9_P2_MASK) >> MSM8976_S9_P2_SHIFT;
0262 p2[10] = (qfprom_cdata[5] & MSM8976_S10_P2_MASK) >> MSM8976_S10_P2_SHIFT;
0263
0264 for (i = 0; i < priv->num_sensors; i++)
0265 p2[i] = ((base1 + p2[i]) << 2);
0266 fallthrough;
0267 case ONE_PT_CALIB2:
0268 base0 = qfprom_cdata[0] & MSM8976_BASE0_MASK;
0269 p1[0] = (qfprom_cdata[0] & MSM8976_S0_P1_MASK) >> MSM8976_S0_P1_SHIFT;
0270 p1[1] = (qfprom_cdata[0] & MSM8976_S1_P1_MASK) >> MSM8976_S1_P1_SHIFT;
0271 p1[2] = (qfprom_cdata[1] & MSM8976_S2_P1_MASK) >> MSM8976_S2_P1_SHIFT;
0272 p1[3] = (qfprom_cdata[1] & MSM8976_S3_P1_MASK) >> MSM8976_S3_P1_SHIFT;
0273 p1[4] = (qfprom_cdata[2] & MSM8976_S4_P1_MASK) >> MSM8976_S4_P1_SHIFT;
0274 p1[5] = (qfprom_cdata[2] & MSM8976_S5_P1_MASK) >> MSM8976_S5_P1_SHIFT;
0275 p1[6] = (qfprom_cdata[3] & MSM8976_S6_P1_MASK) >> MSM8976_S6_P1_SHIFT;
0276 p1[7] = (qfprom_cdata[3] & MSM8976_S7_P1_MASK) >> MSM8976_S7_P1_SHIFT;
0277 p1[8] = (qfprom_cdata[4] & MSM8976_S8_P1_MASK) >> MSM8976_S8_P1_SHIFT;
0278 p1[9] = (qfprom_cdata[4] & MSM8976_S9_P1_MASK) >> MSM8976_S9_P1_SHIFT;
0279 p1[10] = (qfprom_cdata[4] & MSM8976_S10_P1_MASK) >> MSM8976_S10_P1_SHIFT;
0280 tmp = (qfprom_cdata[5] & MSM8976_S10_P1_MASK_1) << MSM8976_S10_P1_SHIFT_1;
0281 p1[10] |= tmp;
0282
0283 for (i = 0; i < priv->num_sensors; i++)
0284 p1[i] = (((base0) + p1[i]) << 2);
0285 break;
0286 default:
0287 for (i = 0; i < priv->num_sensors; i++) {
0288 p1[i] = 500;
0289 p2[i] = 780;
0290 }
0291 break;
0292 }
0293
0294 compute_intercept_slope_8976(priv, p1, p2, mode);
0295 kfree(qfprom_cdata);
0296
0297 return 0;
0298 }
0299
0300
0301
0302 static struct tsens_features tsens_v1_feat = {
0303 .ver_major = VER_1_X,
0304 .crit_int = 0,
0305 .adc = 1,
0306 .srot_split = 1,
0307 .max_sensors = 11,
0308 };
0309
0310 static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
0311
0312
0313 [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
0314 [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
0315 [VER_STEP] = REG_FIELD(SROT_HW_VER_OFF, 0, 15),
0316
0317 [TSENS_EN] = REG_FIELD(SROT_CTRL_OFF, 0, 0),
0318 [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1, 1),
0319 [SENSOR_EN] = REG_FIELD(SROT_CTRL_OFF, 3, 13),
0320
0321
0322
0323 [INT_EN] = REG_FIELD(TM_INT_EN_OFF, 0, 0),
0324
0325
0326 REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 0, 9),
0327 REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
0328
0329
0330 REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
0331 REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
0332 [LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 0, 0),
0333 [LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 1, 1),
0334 [LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 2, 2),
0335 [LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 3, 3),
0336 [LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 4, 4),
0337 [LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 5, 5),
0338 [LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 6, 6),
0339 [LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 7, 7),
0340 [UP_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 8, 8),
0341 [UP_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 9, 9),
0342 [UP_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10),
0343 [UP_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11),
0344 [UP_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12),
0345 [UP_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13),
0346 [UP_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14),
0347 [UP_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15),
0348
0349
0350
0351
0352 REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP, TM_Sn_STATUS_OFF, 0, 9),
0353 REG_FIELD_FOR_EACH_SENSOR11(VALID, TM_Sn_STATUS_OFF, 14, 14),
0354
0355 REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS, TM_Sn_STATUS_OFF, 10, 10),
0356 REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
0357 REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
0358
0359 REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS, TM_Sn_STATUS_OFF, 13, 13),
0360
0361
0362 [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
0363 };
0364
0365 static const struct tsens_ops ops_generic_v1 = {
0366 .init = init_common,
0367 .calibrate = calibrate_v1,
0368 .get_temp = get_temp_tsens_valid,
0369 };
0370
0371 struct tsens_plat_data data_tsens_v1 = {
0372 .ops = &ops_generic_v1,
0373 .feat = &tsens_v1_feat,
0374 .fields = tsens_v1_regfields,
0375 };
0376
0377 static const struct tsens_ops ops_8976 = {
0378 .init = init_common,
0379 .calibrate = calibrate_8976,
0380 .get_temp = get_temp_tsens_valid,
0381 };
0382
0383
0384 struct tsens_plat_data data_8976 = {
0385 .num_sensors = 11,
0386 .ops = &ops_8976,
0387 .hw_ids = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
0388 .feat = &tsens_v1_feat,
0389 .fields = tsens_v1_regfields,
0390 };