linux/drivers/thermal/qcom/tsens-v1.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (c) 2019, Linaro Limited
   4 */
   5
   6#include <linux/bitops.h>
   7#include <linux/regmap.h>
   8#include <linux/delay.h>
   9#include <linux/slab.h>
  10#include "tsens.h"
  11
  12/* ----- SROT ------ */
  13#define SROT_HW_VER_OFF 0x0000
  14#define SROT_CTRL_OFF           0x0004
  15
  16/* ----- TM ------ */
  17#define TM_INT_EN_OFF                           0x0000
  18#define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF       0x0004
  19#define TM_Sn_STATUS_OFF                        0x0044
  20#define TM_TRDY_OFF                             0x0084
  21#define TM_HIGH_LOW_INT_STATUS_OFF              0x0088
  22#define TM_HIGH_LOW_Sn_INT_THRESHOLD_OFF        0x0090
  23
  24/* eeprom layout data for msm8956/76 (v1) */
  25#define MSM8976_BASE0_MASK      0xff
  26#define MSM8976_BASE1_MASK      0xff
  27#define MSM8976_BASE1_SHIFT     8
  28
  29#define MSM8976_S0_P1_MASK      0x3f00
  30#define MSM8976_S1_P1_MASK      0x3f00000
  31#define MSM8976_S2_P1_MASK      0x3f
  32#define MSM8976_S3_P1_MASK      0x3f000
  33#define MSM8976_S4_P1_MASK      0x3f00
  34#define MSM8976_S5_P1_MASK      0x3f00000
  35#define MSM8976_S6_P1_MASK      0x3f
  36#define MSM8976_S7_P1_MASK      0x3f000
  37#define MSM8976_S8_P1_MASK      0x1f8
  38#define MSM8976_S9_P1_MASK      0x1f8000
  39#define MSM8976_S10_P1_MASK     0xf8000000
  40#define MSM8976_S10_P1_MASK_1   0x1
  41
  42#define MSM8976_S0_P2_MASK      0xfc000
  43#define MSM8976_S1_P2_MASK      0xfc000000
  44#define MSM8976_S2_P2_MASK      0xfc0
  45#define MSM8976_S3_P2_MASK      0xfc0000
  46#define MSM8976_S4_P2_MASK      0xfc000
  47#define MSM8976_S5_P2_MASK      0xfc000000
  48#define MSM8976_S6_P2_MASK      0xfc0
  49#define MSM8976_S7_P2_MASK      0xfc0000
  50#define MSM8976_S8_P2_MASK      0x7e00
  51#define MSM8976_S9_P2_MASK      0x7e00000
  52#define MSM8976_S10_P2_MASK     0x7e
  53
  54#define MSM8976_S0_P1_SHIFT     8
  55#define MSM8976_S1_P1_SHIFT     20
  56#define MSM8976_S2_P1_SHIFT     0
  57#define MSM8976_S3_P1_SHIFT     12
  58#define MSM8976_S4_P1_SHIFT     8
  59#define MSM8976_S5_P1_SHIFT     20
  60#define MSM8976_S6_P1_SHIFT     0
  61#define MSM8976_S7_P1_SHIFT     12
  62#define MSM8976_S8_P1_SHIFT     3
  63#define MSM8976_S9_P1_SHIFT     15
  64#define MSM8976_S10_P1_SHIFT    27
  65#define MSM8976_S10_P1_SHIFT_1  0
  66
  67#define MSM8976_S0_P2_SHIFT     14
  68#define MSM8976_S1_P2_SHIFT     26
  69#define MSM8976_S2_P2_SHIFT     6
  70#define MSM8976_S3_P2_SHIFT     18
  71#define MSM8976_S4_P2_SHIFT     14
  72#define MSM8976_S5_P2_SHIFT     26
  73#define MSM8976_S6_P2_SHIFT     6
  74#define MSM8976_S7_P2_SHIFT     18
  75#define MSM8976_S8_P2_SHIFT     9
  76#define MSM8976_S9_P2_SHIFT     21
  77#define MSM8976_S10_P2_SHIFT    1
  78
  79#define MSM8976_CAL_SEL_MASK    0x3
  80
  81#define MSM8976_CAL_DEGC_PT1    30
  82#define MSM8976_CAL_DEGC_PT2    120
  83#define MSM8976_SLOPE_FACTOR    1000
  84#define MSM8976_SLOPE_DEFAULT   3200
  85
  86/* eeprom layout data for qcs404/405 (v1) */
  87#define BASE0_MASK      0x000007f8
  88#define BASE1_MASK      0x0007f800
  89#define BASE0_SHIFT     3
  90#define BASE1_SHIFT     11
  91
  92#define S0_P1_MASK      0x0000003f
  93#define S1_P1_MASK      0x0003f000
  94#define S2_P1_MASK      0x3f000000
  95#define S3_P1_MASK      0x000003f0
  96#define S4_P1_MASK      0x003f0000
  97#define S5_P1_MASK      0x0000003f
  98#define S6_P1_MASK      0x0003f000
  99#define S7_P1_MASK      0x3f000000
 100#define S8_P1_MASK      0x000003f0
 101#define S9_P1_MASK      0x003f0000
 102
 103#define S0_P2_MASK      0x00000fc0
 104#define S1_P2_MASK      0x00fc0000
 105#define S2_P2_MASK_1_0  0xc0000000
 106#define S2_P2_MASK_5_2  0x0000000f
 107#define S3_P2_MASK      0x0000fc00
 108#define S4_P2_MASK      0x0fc00000
 109#define S5_P2_MASK      0x00000fc0
 110#define S6_P2_MASK      0x00fc0000
 111#define S7_P2_MASK_1_0  0xc0000000
 112#define S7_P2_MASK_5_2  0x0000000f
 113#define S8_P2_MASK      0x0000fc00
 114#define S9_P2_MASK      0x0fc00000
 115
 116#define S0_P1_SHIFT     0
 117#define S0_P2_SHIFT     6
 118#define S1_P1_SHIFT     12
 119#define S1_P2_SHIFT     18
 120#define S2_P1_SHIFT     24
 121#define S2_P2_SHIFT_1_0 30
 122
 123#define S2_P2_SHIFT_5_2 0
 124#define S3_P1_SHIFT     4
 125#define S3_P2_SHIFT     10
 126#define S4_P1_SHIFT     16
 127#define S4_P2_SHIFT     22
 128
 129#define S5_P1_SHIFT     0
 130#define S5_P2_SHIFT     6
 131#define S6_P1_SHIFT     12
 132#define S6_P2_SHIFT     18
 133#define S7_P1_SHIFT     24
 134#define S7_P2_SHIFT_1_0 30
 135
 136#define S7_P2_SHIFT_5_2 0
 137#define S8_P1_SHIFT     4
 138#define S8_P2_SHIFT     10
 139#define S9_P1_SHIFT     16
 140#define S9_P2_SHIFT     22
 141
 142#define CAL_SEL_MASK    7
 143#define CAL_SEL_SHIFT   0
 144
 145static void compute_intercept_slope_8976(struct tsens_priv *priv,
 146                              u32 *p1, u32 *p2, u32 mode)
 147{
 148        int i;
 149
 150        priv->sensor[0].slope = 3313;
 151        priv->sensor[1].slope = 3275;
 152        priv->sensor[2].slope = 3320;
 153        priv->sensor[3].slope = 3246;
 154        priv->sensor[4].slope = 3279;
 155        priv->sensor[5].slope = 3257;
 156        priv->sensor[6].slope = 3234;
 157        priv->sensor[7].slope = 3269;
 158        priv->sensor[8].slope = 3255;
 159        priv->sensor[9].slope = 3239;
 160        priv->sensor[10].slope = 3286;
 161
 162        for (i = 0; i < priv->num_sensors; i++) {
 163                priv->sensor[i].offset = (p1[i] * MSM8976_SLOPE_FACTOR) -
 164                                (MSM8976_CAL_DEGC_PT1 *
 165                                priv->sensor[i].slope);
 166        }
 167}
 168
 169static int calibrate_v1(struct tsens_priv *priv)
 170{
 171        u32 base0 = 0, base1 = 0;
 172        u32 p1[10], p2[10];
 173        u32 mode = 0, lsb = 0, msb = 0;
 174        u32 *qfprom_cdata;
 175        int i;
 176
 177        qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
 178        if (IS_ERR(qfprom_cdata))
 179                return PTR_ERR(qfprom_cdata);
 180
 181        mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
 182        dev_dbg(priv->dev, "calibration mode is %d\n", mode);
 183
 184        switch (mode) {
 185        case TWO_PT_CALIB:
 186                base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
 187                p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
 188                p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
 189                /* This value is split over two registers, 2 bits and 4 bits */
 190                lsb   = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
 191                msb   = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
 192                p2[2] = msb << 2 | lsb;
 193                p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
 194                p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
 195                p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
 196                p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
 197                /* This value is split over two registers, 2 bits and 4 bits */
 198                lsb   = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
 199                msb   = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
 200                p2[7] = msb << 2 | lsb;
 201                p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
 202                p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
 203                for (i = 0; i < priv->num_sensors; i++)
 204                        p2[i] = ((base1 + p2[i]) << 2);
 205                fallthrough;
 206        case ONE_PT_CALIB2:
 207                base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
 208                p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
 209                p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
 210                p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
 211                p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
 212                p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
 213                p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
 214                p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
 215                p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
 216                p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
 217                p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
 218                for (i = 0; i < priv->num_sensors; i++)
 219                        p1[i] = (((base0) + p1[i]) << 2);
 220                break;
 221        default:
 222                for (i = 0; i < priv->num_sensors; i++) {
 223                        p1[i] = 500;
 224                        p2[i] = 780;
 225                }
 226                break;
 227        }
 228
 229        compute_intercept_slope(priv, p1, p2, mode);
 230        kfree(qfprom_cdata);
 231
 232        return 0;
 233}
 234
 235static int calibrate_8976(struct tsens_priv *priv)
 236{
 237        int base0 = 0, base1 = 0, i;
 238        u32 p1[11], p2[11];
 239        int mode = 0, tmp = 0;
 240        u32 *qfprom_cdata;
 241
 242        qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
 243        if (IS_ERR(qfprom_cdata))
 244                return PTR_ERR(qfprom_cdata);
 245
 246        mode = (qfprom_cdata[4] & MSM8976_CAL_SEL_MASK);
 247        dev_dbg(priv->dev, "calibration mode is %d\n", mode);
 248
 249        switch (mode) {
 250        case TWO_PT_CALIB:
 251                base1 = (qfprom_cdata[2] & MSM8976_BASE1_MASK) >> MSM8976_BASE1_SHIFT;
 252                p2[0] = (qfprom_cdata[0] & MSM8976_S0_P2_MASK) >> MSM8976_S0_P2_SHIFT;
 253                p2[1] = (qfprom_cdata[0] & MSM8976_S1_P2_MASK) >> MSM8976_S1_P2_SHIFT;
 254                p2[2] = (qfprom_cdata[1] & MSM8976_S2_P2_MASK) >> MSM8976_S2_P2_SHIFT;
 255                p2[3] = (qfprom_cdata[1] & MSM8976_S3_P2_MASK) >> MSM8976_S3_P2_SHIFT;
 256                p2[4] = (qfprom_cdata[2] & MSM8976_S4_P2_MASK) >> MSM8976_S4_P2_SHIFT;
 257                p2[5] = (qfprom_cdata[2] & MSM8976_S5_P2_MASK) >> MSM8976_S5_P2_SHIFT;
 258                p2[6] = (qfprom_cdata[3] & MSM8976_S6_P2_MASK) >> MSM8976_S6_P2_SHIFT;
 259                p2[7] = (qfprom_cdata[3] & MSM8976_S7_P2_MASK) >> MSM8976_S7_P2_SHIFT;
 260                p2[8] = (qfprom_cdata[4] & MSM8976_S8_P2_MASK) >> MSM8976_S8_P2_SHIFT;
 261                p2[9] = (qfprom_cdata[4] & MSM8976_S9_P2_MASK) >> MSM8976_S9_P2_SHIFT;
 262                p2[10] = (qfprom_cdata[5] & MSM8976_S10_P2_MASK) >> MSM8976_S10_P2_SHIFT;
 263
 264                for (i = 0; i < priv->num_sensors; i++)
 265                        p2[i] = ((base1 + p2[i]) << 2);
 266                fallthrough;
 267        case ONE_PT_CALIB2:
 268                base0 = qfprom_cdata[0] & MSM8976_BASE0_MASK;
 269                p1[0] = (qfprom_cdata[0] & MSM8976_S0_P1_MASK) >> MSM8976_S0_P1_SHIFT;
 270                p1[1] = (qfprom_cdata[0] & MSM8976_S1_P1_MASK) >> MSM8976_S1_P1_SHIFT;
 271                p1[2] = (qfprom_cdata[1] & MSM8976_S2_P1_MASK) >> MSM8976_S2_P1_SHIFT;
 272                p1[3] = (qfprom_cdata[1] & MSM8976_S3_P1_MASK) >> MSM8976_S3_P1_SHIFT;
 273                p1[4] = (qfprom_cdata[2] & MSM8976_S4_P1_MASK) >> MSM8976_S4_P1_SHIFT;
 274                p1[5] = (qfprom_cdata[2] & MSM8976_S5_P1_MASK) >> MSM8976_S5_P1_SHIFT;
 275                p1[6] = (qfprom_cdata[3] & MSM8976_S6_P1_MASK) >> MSM8976_S6_P1_SHIFT;
 276                p1[7] = (qfprom_cdata[3] & MSM8976_S7_P1_MASK) >> MSM8976_S7_P1_SHIFT;
 277                p1[8] = (qfprom_cdata[4] & MSM8976_S8_P1_MASK) >> MSM8976_S8_P1_SHIFT;
 278                p1[9] = (qfprom_cdata[4] & MSM8976_S9_P1_MASK) >> MSM8976_S9_P1_SHIFT;
 279                p1[10] = (qfprom_cdata[4] & MSM8976_S10_P1_MASK) >> MSM8976_S10_P1_SHIFT;
 280                tmp = (qfprom_cdata[5] & MSM8976_S10_P1_MASK_1) << MSM8976_S10_P1_SHIFT_1;
 281                p1[10] |= tmp;
 282
 283                for (i = 0; i < priv->num_sensors; i++)
 284                        p1[i] = (((base0) + p1[i]) << 2);
 285                break;
 286        default:
 287                for (i = 0; i < priv->num_sensors; i++) {
 288                        p1[i] = 500;
 289                        p2[i] = 780;
 290                }
 291                break;
 292        }
 293
 294        compute_intercept_slope_8976(priv, p1, p2, mode);
 295        kfree(qfprom_cdata);
 296
 297        return 0;
 298}
 299
 300/* v1.x: msm8956,8976,qcs404,405 */
 301
 302static struct tsens_features tsens_v1_feat = {
 303        .ver_major      = VER_1_X,
 304        .crit_int       = 0,
 305        .adc            = 1,
 306        .srot_split     = 1,
 307        .max_sensors    = 11,
 308};
 309
 310static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
 311        /* ----- SROT ------ */
 312        /* VERSION */
 313        [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
 314        [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
 315        [VER_STEP]  = REG_FIELD(SROT_HW_VER_OFF,  0, 15),
 316        /* CTRL_OFFSET */
 317        [TSENS_EN]     = REG_FIELD(SROT_CTRL_OFF, 0,  0),
 318        [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1,  1),
 319        [SENSOR_EN]    = REG_FIELD(SROT_CTRL_OFF, 3, 13),
 320
 321        /* ----- TM ------ */
 322        /* INTERRUPT ENABLE */
 323        [INT_EN]     = REG_FIELD(TM_INT_EN_OFF, 0, 0),
 324
 325        /* UPPER/LOWER TEMPERATURE THRESHOLDS */
 326        REG_FIELD_FOR_EACH_SENSOR11(LOW_THRESH,    TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF,  0,  9),
 327        REG_FIELD_FOR_EACH_SENSOR11(UP_THRESH,     TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 10, 19),
 328
 329        /* UPPER/LOWER INTERRUPTS [CLEAR/STATUS] */
 330        REG_FIELD_FOR_EACH_SENSOR11(LOW_INT_CLEAR, TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 20, 20),
 331        REG_FIELD_FOR_EACH_SENSOR11(UP_INT_CLEAR,  TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF, 21, 21),
 332        [LOW_INT_STATUS_0] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  0,  0),
 333        [LOW_INT_STATUS_1] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  1,  1),
 334        [LOW_INT_STATUS_2] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  2,  2),
 335        [LOW_INT_STATUS_3] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  3,  3),
 336        [LOW_INT_STATUS_4] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  4,  4),
 337        [LOW_INT_STATUS_5] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  5,  5),
 338        [LOW_INT_STATUS_6] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  6,  6),
 339        [LOW_INT_STATUS_7] = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  7,  7),
 340        [UP_INT_STATUS_0]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  8,  8),
 341        [UP_INT_STATUS_1]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF,  9,  9),
 342        [UP_INT_STATUS_2]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 10, 10),
 343        [UP_INT_STATUS_3]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 11, 11),
 344        [UP_INT_STATUS_4]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 12, 12),
 345        [UP_INT_STATUS_5]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 13, 13),
 346        [UP_INT_STATUS_6]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 14, 14),
 347        [UP_INT_STATUS_7]  = REG_FIELD(TM_HIGH_LOW_INT_STATUS_OFF, 15, 15),
 348
 349        /* NO CRITICAL INTERRUPT SUPPORT on v1 */
 350
 351        /* Sn_STATUS */
 352        REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP,    TM_Sn_STATUS_OFF,  0,  9),
 353        REG_FIELD_FOR_EACH_SENSOR11(VALID,        TM_Sn_STATUS_OFF, 14, 14),
 354        /* xxx_STATUS bits: 1 == threshold violated */
 355        REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS,   TM_Sn_STATUS_OFF, 10, 10),
 356        REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
 357        REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
 358        /* No CRITICAL field on v1.x */
 359        REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS,   TM_Sn_STATUS_OFF, 13, 13),
 360
 361        /* TRDY: 1=ready, 0=in progress */
 362        [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
 363};
 364
 365static const struct tsens_ops ops_generic_v1 = {
 366        .init           = init_common,
 367        .calibrate      = calibrate_v1,
 368        .get_temp       = get_temp_tsens_valid,
 369};
 370
 371struct tsens_plat_data data_tsens_v1 = {
 372        .ops            = &ops_generic_v1,
 373        .feat           = &tsens_v1_feat,
 374        .fields = tsens_v1_regfields,
 375};
 376
 377static const struct tsens_ops ops_8976 = {
 378        .init           = init_common,
 379        .calibrate      = calibrate_8976,
 380        .get_temp       = get_temp_tsens_valid,
 381};
 382
 383/* Valid for both MSM8956 and MSM8976. */
 384struct tsens_plat_data data_8976 = {
 385        .num_sensors    = 11,
 386        .ops            = &ops_8976,
 387        .hw_ids         = (unsigned int[]){0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
 388        .feat           = &tsens_v1_feat,
 389        .fields         = tsens_v1_regfields,
 390};
 391