Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2019, Linaro Limited
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 /* ----- SROT ------ */
0013 #define SROT_HW_VER_OFF 0x0000
0014 #define SROT_CTRL_OFF       0x0004
0015 
0016 /* ----- TM ------ */
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 /* eeprom layout data for msm8956/76 (v1) */
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 /* eeprom layout data for qcs404/405 (v1) */
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         /* This value is split over two registers, 2 bits and 4 bits */
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         /* This value is split over two registers, 2 bits and 4 bits */
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 /* v1.x: msm8956,8976,qcs404,405 */
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     /* ----- SROT ------ */
0312     /* VERSION */
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     /* CTRL_OFFSET */
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     /* ----- TM ------ */
0322     /* INTERRUPT ENABLE */
0323     [INT_EN]     = REG_FIELD(TM_INT_EN_OFF, 0, 0),
0324 
0325     /* UPPER/LOWER TEMPERATURE THRESHOLDS */
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     /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
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     /* NO CRITICAL INTERRUPT SUPPORT on v1 */
0350 
0351     /* Sn_STATUS */
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     /* xxx_STATUS bits: 1 == threshold violated */
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     /* No CRITICAL field on v1.x */
0359     REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS,   TM_Sn_STATUS_OFF, 13, 13),
0360 
0361     /* TRDY: 1=ready, 0=in progress */
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 /* Valid for both MSM8956 and MSM8976. */
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 };