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 }; 195