root/drivers/thermal/qcom/tsens-v1.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. calibrate_v1

   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 "tsens.h"
  10 
  11 /* ----- SROT ------ */
  12 #define SROT_HW_VER_OFF 0x0000
  13 #define SROT_CTRL_OFF           0x0004
  14 
  15 /* ----- TM ------ */
  16 #define TM_INT_EN_OFF                           0x0000
  17 #define TM_Sn_UPPER_LOWER_STATUS_CTRL_OFF       0x0004
  18 #define TM_Sn_STATUS_OFF                        0x0044
  19 #define TM_TRDY_OFF                             0x0084
  20 
  21 /* eeprom layout data for qcs404/405 (v1) */
  22 #define BASE0_MASK      0x000007f8
  23 #define BASE1_MASK      0x0007f800
  24 #define BASE0_SHIFT     3
  25 #define BASE1_SHIFT     11
  26 
  27 #define S0_P1_MASK      0x0000003f
  28 #define S1_P1_MASK      0x0003f000
  29 #define S2_P1_MASK      0x3f000000
  30 #define S3_P1_MASK      0x000003f0
  31 #define S4_P1_MASK      0x003f0000
  32 #define S5_P1_MASK      0x0000003f
  33 #define S6_P1_MASK      0x0003f000
  34 #define S7_P1_MASK      0x3f000000
  35 #define S8_P1_MASK      0x000003f0
  36 #define S9_P1_MASK      0x003f0000
  37 
  38 #define S0_P2_MASK      0x00000fc0
  39 #define S1_P2_MASK      0x00fc0000
  40 #define S2_P2_MASK_1_0  0xc0000000
  41 #define S2_P2_MASK_5_2  0x0000000f
  42 #define S3_P2_MASK      0x0000fc00
  43 #define S4_P2_MASK      0x0fc00000
  44 #define S5_P2_MASK      0x00000fc0
  45 #define S6_P2_MASK      0x00fc0000
  46 #define S7_P2_MASK_1_0  0xc0000000
  47 #define S7_P2_MASK_5_2  0x0000000f
  48 #define S8_P2_MASK      0x0000fc00
  49 #define S9_P2_MASK      0x0fc00000
  50 
  51 #define S0_P1_SHIFT     0
  52 #define S0_P2_SHIFT     6
  53 #define S1_P1_SHIFT     12
  54 #define S1_P2_SHIFT     18
  55 #define S2_P1_SHIFT     24
  56 #define S2_P2_SHIFT_1_0 30
  57 
  58 #define S2_P2_SHIFT_5_2 0
  59 #define S3_P1_SHIFT     4
  60 #define S3_P2_SHIFT     10
  61 #define S4_P1_SHIFT     16
  62 #define S4_P2_SHIFT     22
  63 
  64 #define S5_P1_SHIFT     0
  65 #define S5_P2_SHIFT     6
  66 #define S6_P1_SHIFT     12
  67 #define S6_P2_SHIFT     18
  68 #define S7_P1_SHIFT     24
  69 #define S7_P2_SHIFT_1_0 30
  70 
  71 #define S7_P2_SHIFT_5_2 0
  72 #define S8_P1_SHIFT     4
  73 #define S8_P2_SHIFT     10
  74 #define S9_P1_SHIFT     16
  75 #define S9_P2_SHIFT     22
  76 
  77 #define CAL_SEL_MASK    7
  78 #define CAL_SEL_SHIFT   0
  79 
  80 static int calibrate_v1(struct tsens_priv *priv)
  81 {
  82         u32 base0 = 0, base1 = 0;
  83         u32 p1[10], p2[10];
  84         u32 mode = 0, lsb = 0, msb = 0;
  85         u32 *qfprom_cdata;
  86         int i;
  87 
  88         qfprom_cdata = (u32 *)qfprom_read(priv->dev, "calib");
  89         if (IS_ERR(qfprom_cdata))
  90                 return PTR_ERR(qfprom_cdata);
  91 
  92         mode = (qfprom_cdata[4] & CAL_SEL_MASK) >> CAL_SEL_SHIFT;
  93         dev_dbg(priv->dev, "calibration mode is %d\n", mode);
  94 
  95         switch (mode) {
  96         case TWO_PT_CALIB:
  97                 base1 = (qfprom_cdata[4] & BASE1_MASK) >> BASE1_SHIFT;
  98                 p2[0] = (qfprom_cdata[0] & S0_P2_MASK) >> S0_P2_SHIFT;
  99                 p2[1] = (qfprom_cdata[0] & S1_P2_MASK) >> S1_P2_SHIFT;
 100                 /* This value is split over two registers, 2 bits and 4 bits */
 101                 lsb   = (qfprom_cdata[0] & S2_P2_MASK_1_0) >> S2_P2_SHIFT_1_0;
 102                 msb   = (qfprom_cdata[1] & S2_P2_MASK_5_2) >> S2_P2_SHIFT_5_2;
 103                 p2[2] = msb << 2 | lsb;
 104                 p2[3] = (qfprom_cdata[1] & S3_P2_MASK) >> S3_P2_SHIFT;
 105                 p2[4] = (qfprom_cdata[1] & S4_P2_MASK) >> S4_P2_SHIFT;
 106                 p2[5] = (qfprom_cdata[2] & S5_P2_MASK) >> S5_P2_SHIFT;
 107                 p2[6] = (qfprom_cdata[2] & S6_P2_MASK) >> S6_P2_SHIFT;
 108                 /* This value is split over two registers, 2 bits and 4 bits */
 109                 lsb   = (qfprom_cdata[2] & S7_P2_MASK_1_0) >> S7_P2_SHIFT_1_0;
 110                 msb   = (qfprom_cdata[3] & S7_P2_MASK_5_2) >> S7_P2_SHIFT_5_2;
 111                 p2[7] = msb << 2 | lsb;
 112                 p2[8] = (qfprom_cdata[3] & S8_P2_MASK) >> S8_P2_SHIFT;
 113                 p2[9] = (qfprom_cdata[3] & S9_P2_MASK) >> S9_P2_SHIFT;
 114                 for (i = 0; i < priv->num_sensors; i++)
 115                         p2[i] = ((base1 + p2[i]) << 2);
 116                 /* Fall through */
 117         case ONE_PT_CALIB2:
 118                 base0 = (qfprom_cdata[4] & BASE0_MASK) >> BASE0_SHIFT;
 119                 p1[0] = (qfprom_cdata[0] & S0_P1_MASK) >> S0_P1_SHIFT;
 120                 p1[1] = (qfprom_cdata[0] & S1_P1_MASK) >> S1_P1_SHIFT;
 121                 p1[2] = (qfprom_cdata[0] & S2_P1_MASK) >> S2_P1_SHIFT;
 122                 p1[3] = (qfprom_cdata[1] & S3_P1_MASK) >> S3_P1_SHIFT;
 123                 p1[4] = (qfprom_cdata[1] & S4_P1_MASK) >> S4_P1_SHIFT;
 124                 p1[5] = (qfprom_cdata[2] & S5_P1_MASK) >> S5_P1_SHIFT;
 125                 p1[6] = (qfprom_cdata[2] & S6_P1_MASK) >> S6_P1_SHIFT;
 126                 p1[7] = (qfprom_cdata[2] & S7_P1_MASK) >> S7_P1_SHIFT;
 127                 p1[8] = (qfprom_cdata[3] & S8_P1_MASK) >> S8_P1_SHIFT;
 128                 p1[9] = (qfprom_cdata[3] & S9_P1_MASK) >> S9_P1_SHIFT;
 129                 for (i = 0; i < priv->num_sensors; i++)
 130                         p1[i] = (((base0) + p1[i]) << 2);
 131                 break;
 132         default:
 133                 for (i = 0; i < priv->num_sensors; i++) {
 134                         p1[i] = 500;
 135                         p2[i] = 780;
 136                 }
 137                 break;
 138         }
 139 
 140         compute_intercept_slope(priv, p1, p2, mode);
 141         kfree(qfprom_cdata);
 142 
 143         return 0;
 144 }
 145 
 146 /* v1.x: qcs404,405 */
 147 
 148 static const struct tsens_features tsens_v1_feat = {
 149         .ver_major      = VER_1_X,
 150         .crit_int       = 0,
 151         .adc            = 1,
 152         .srot_split     = 1,
 153         .max_sensors    = 11,
 154 };
 155 
 156 static const struct reg_field tsens_v1_regfields[MAX_REGFIELDS] = {
 157         /* ----- SROT ------ */
 158         /* VERSION */
 159         [VER_MAJOR] = REG_FIELD(SROT_HW_VER_OFF, 28, 31),
 160         [VER_MINOR] = REG_FIELD(SROT_HW_VER_OFF, 16, 27),
 161         [VER_STEP]  = REG_FIELD(SROT_HW_VER_OFF,  0, 15),
 162         /* CTRL_OFFSET */
 163         [TSENS_EN]     = REG_FIELD(SROT_CTRL_OFF, 0,  0),
 164         [TSENS_SW_RST] = REG_FIELD(SROT_CTRL_OFF, 1,  1),
 165         [SENSOR_EN]    = REG_FIELD(SROT_CTRL_OFF, 3, 13),
 166 
 167         /* ----- TM ------ */
 168         /* INTERRUPT ENABLE */
 169         [INT_EN]     = REG_FIELD(TM_INT_EN_OFF, 0, 0),
 170 
 171         /* Sn_STATUS */
 172         REG_FIELD_FOR_EACH_SENSOR11(LAST_TEMP,    TM_Sn_STATUS_OFF,  0,  9),
 173         REG_FIELD_FOR_EACH_SENSOR11(VALID,        TM_Sn_STATUS_OFF, 14, 14),
 174         REG_FIELD_FOR_EACH_SENSOR11(MIN_STATUS,   TM_Sn_STATUS_OFF, 10, 10),
 175         REG_FIELD_FOR_EACH_SENSOR11(LOWER_STATUS, TM_Sn_STATUS_OFF, 11, 11),
 176         REG_FIELD_FOR_EACH_SENSOR11(UPPER_STATUS, TM_Sn_STATUS_OFF, 12, 12),
 177         /* No CRITICAL field on v1.x */
 178         REG_FIELD_FOR_EACH_SENSOR11(MAX_STATUS,   TM_Sn_STATUS_OFF, 13, 13),
 179 
 180         /* TRDY: 1=ready, 0=in progress */
 181         [TRDY] = REG_FIELD(TM_TRDY_OFF, 0, 0),
 182 };
 183 
 184 static const struct tsens_ops ops_generic_v1 = {
 185         .init           = init_common,
 186         .calibrate      = calibrate_v1,
 187         .get_temp       = get_temp_tsens_valid,
 188 };
 189 
 190 const struct tsens_plat_data data_tsens_v1 = {
 191         .ops            = &ops_generic_v1,
 192         .feat           = &tsens_v1_feat,
 193         .fields = tsens_v1_regfields,
 194 };

/* [<][>][^][v][top][bottom][index][help] */