exynos_tmu.c (fccfe0993b5dc550e5f9fbb716fb0b588c5fdbc1) | exynos_tmu.c (199b3e3c860cdf3f092e7cbb2bf08b8a96ed4beb) |
---|---|
1/* 2 * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit) 3 * 4 * Copyright (C) 2014 Samsung Electronics 5 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 6 * Lukasz Majewski <l.majewski@samsung.com> 7 * 8 * Copyright (C) 2011 Samsung Electronics --- 163 unchanged lines hidden (view full) --- 172 173#define EXYNOS_NOISE_CANCEL_MODE 4 174 175#define MCELSIUS 1000 176/** 177 * struct exynos_tmu_data : A structure to hold the private data of the TMU 178 driver 179 * @id: identifier of the one instance of the TMU controller. | 1/* 2 * exynos_tmu.c - Samsung EXYNOS TMU (Thermal Management Unit) 3 * 4 * Copyright (C) 2014 Samsung Electronics 5 * Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> 6 * Lukasz Majewski <l.majewski@samsung.com> 7 * 8 * Copyright (C) 2011 Samsung Electronics --- 163 unchanged lines hidden (view full) --- 172 173#define EXYNOS_NOISE_CANCEL_MODE 4 174 175#define MCELSIUS 1000 176/** 177 * struct exynos_tmu_data : A structure to hold the private data of the TMU 178 driver 179 * @id: identifier of the one instance of the TMU controller. |
180 * @pdata: pointer to the tmu platform/configuration data | |
181 * @base: base address of the single instance of the TMU controller. 182 * @base_second: base address of the common registers of the TMU controller. 183 * @irq: irq number of the TMU controller. 184 * @soc: id of the SOC type. 185 * @irq_work: pointer to the irq work structure. 186 * @lock: lock to implement synchronization. 187 * @clk: pointer to the clock structure. 188 * @clk_sec: pointer to the clock structure for accessing the base_second. 189 * @sclk: pointer to the clock structure for accessing the tmu special clk. | 180 * @base: base address of the single instance of the TMU controller. 181 * @base_second: base address of the common registers of the TMU controller. 182 * @irq: irq number of the TMU controller. 183 * @soc: id of the SOC type. 184 * @irq_work: pointer to the irq work structure. 185 * @lock: lock to implement synchronization. 186 * @clk: pointer to the clock structure. 187 * @clk_sec: pointer to the clock structure for accessing the base_second. 188 * @sclk: pointer to the clock structure for accessing the tmu special clk. |
189 * @cal_type: calibration type for temperature |
|
190 * @efuse_value: SoC defined fuse value 191 * @min_efuse_value: minimum valid trimming data 192 * @max_efuse_value: maximum valid trimming data 193 * @temp_error1: fused value of the first point trim. 194 * @temp_error2: fused value of the second point trim. 195 * @gain: gain of amplifier in the positive-TC generator block 196 * 0 < gain <= 15 197 * @reference_voltage: reference voltage of amplifier --- 6 unchanged lines hidden (view full) --- 204 * @tmu_initialize: SoC specific TMU initialization method 205 * @tmu_control: SoC specific TMU control method 206 * @tmu_read: SoC specific TMU temperature read method 207 * @tmu_set_emulation: SoC specific TMU emulation setting method 208 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method 209 */ 210struct exynos_tmu_data { 211 int id; | 190 * @efuse_value: SoC defined fuse value 191 * @min_efuse_value: minimum valid trimming data 192 * @max_efuse_value: maximum valid trimming data 193 * @temp_error1: fused value of the first point trim. 194 * @temp_error2: fused value of the second point trim. 195 * @gain: gain of amplifier in the positive-TC generator block 196 * 0 < gain <= 15 197 * @reference_voltage: reference voltage of amplifier --- 6 unchanged lines hidden (view full) --- 204 * @tmu_initialize: SoC specific TMU initialization method 205 * @tmu_control: SoC specific TMU control method 206 * @tmu_read: SoC specific TMU temperature read method 207 * @tmu_set_emulation: SoC specific TMU emulation setting method 208 * @tmu_clear_irqs: SoC specific TMU interrupts clearing method 209 */ 210struct exynos_tmu_data { 211 int id; |
212 struct exynos_tmu_platform_data *pdata; | |
213 void __iomem *base; 214 void __iomem *base_second; 215 int irq; 216 enum soc_type soc; 217 struct work_struct irq_work; 218 struct mutex lock; 219 struct clk *clk, *clk_sec, *sclk; | 212 void __iomem *base; 213 void __iomem *base_second; 214 int irq; 215 enum soc_type soc; 216 struct work_struct irq_work; 217 struct mutex lock; 218 struct clk *clk, *clk_sec, *sclk; |
219 u32 cal_type; |
|
220 u32 efuse_value; 221 u32 min_efuse_value; 222 u32 max_efuse_value; 223 u16 temp_error1, temp_error2; 224 u8 gain; 225 u8 reference_voltage; 226 struct regulator *regulator; 227 struct thermal_zone_device *tzd; --- 35 unchanged lines hidden (view full) --- 263} 264 265/* 266 * TMU treats temperature as a mapped temperature code. 267 * The temperature is converted differently depending on the calibration type. 268 */ 269static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 270{ | 220 u32 efuse_value; 221 u32 min_efuse_value; 222 u32 max_efuse_value; 223 u16 temp_error1, temp_error2; 224 u8 gain; 225 u8 reference_voltage; 226 struct regulator *regulator; 227 struct thermal_zone_device *tzd; --- 35 unchanged lines hidden (view full) --- 263} 264 265/* 266 * TMU treats temperature as a mapped temperature code. 267 * The temperature is converted differently depending on the calibration type. 268 */ 269static int temp_to_code(struct exynos_tmu_data *data, u8 temp) 270{ |
271 struct exynos_tmu_platform_data *pdata = data->pdata; 272 273 if (pdata->cal_type == TYPE_ONE_POINT_TRIMMING) | 271 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) |
274 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM; 275 276 return (temp - EXYNOS_FIRST_POINT_TRIM) * 277 (data->temp_error2 - data->temp_error1) / 278 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) + 279 data->temp_error1; 280} 281 282/* 283 * Calculate a temperature value from a temperature code. 284 * The unit of the temperature is degree Celsius. 285 */ 286static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code) 287{ | 272 return temp + data->temp_error1 - EXYNOS_FIRST_POINT_TRIM; 273 274 return (temp - EXYNOS_FIRST_POINT_TRIM) * 275 (data->temp_error2 - data->temp_error1) / 276 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) + 277 data->temp_error1; 278} 279 280/* 281 * Calculate a temperature value from a temperature code. 282 * The unit of the temperature is degree Celsius. 283 */ 284static int code_to_temp(struct exynos_tmu_data *data, u16 temp_code) 285{ |
288 struct exynos_tmu_platform_data *pdata = data->pdata; 289 290 if (pdata->cal_type == TYPE_ONE_POINT_TRIMMING) | 286 if (data->cal_type == TYPE_ONE_POINT_TRIMMING) |
291 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM; 292 293 return (temp_code - data->temp_error1) * 294 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) / 295 (data->temp_error2 - data->temp_error1) + 296 EXYNOS_FIRST_POINT_TRIM; 297} 298 --- 215 unchanged lines hidden (view full) --- 514 515out: 516 return ret; 517} 518 519static int exynos5433_tmu_initialize(struct platform_device *pdev) 520{ 521 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 287 return temp_code - data->temp_error1 + EXYNOS_FIRST_POINT_TRIM; 288 289 return (temp_code - data->temp_error1) * 290 (EXYNOS_SECOND_POINT_TRIM - EXYNOS_FIRST_POINT_TRIM) / 291 (data->temp_error2 - data->temp_error1) + 292 EXYNOS_FIRST_POINT_TRIM; 293} 294 --- 215 unchanged lines hidden (view full) --- 510 511out: 512 return ret; 513} 514 515static int exynos5433_tmu_initialize(struct platform_device *pdev) 516{ 517 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
522 struct exynos_tmu_platform_data *pdata = data->pdata; | |
523 struct thermal_zone_device *tz = data->tzd; 524 unsigned int status, trim_info; 525 unsigned int rising_threshold = 0, falling_threshold = 0; 526 int temp, temp_hist; 527 int ret = 0, threshold_code, i, sensor_id, cal_type; 528 529 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 530 if (!status) { --- 10 unchanged lines hidden (view full) --- 541 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); 542 543 /* Read the calibration mode */ 544 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); 545 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) 546 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; 547 548 switch (cal_type) { | 518 struct thermal_zone_device *tz = data->tzd; 519 unsigned int status, trim_info; 520 unsigned int rising_threshold = 0, falling_threshold = 0; 521 int temp, temp_hist; 522 int ret = 0, threshold_code, i, sensor_id, cal_type; 523 524 status = readb(data->base + EXYNOS_TMU_REG_STATUS); 525 if (!status) { --- 10 unchanged lines hidden (view full) --- 536 dev_info(&pdev->dev, "Temperature sensor ID: 0x%x\n", sensor_id); 537 538 /* Read the calibration mode */ 539 writel(trim_info, data->base + EXYNOS_TMU_REG_TRIMINFO); 540 cal_type = (trim_info & EXYNOS5433_TRIMINFO_CALIB_SEL_MASK) 541 >> EXYNOS5433_TRIMINFO_CALIB_SEL_SHIFT; 542 543 switch (cal_type) { |
549 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: 550 pdata->cal_type = TYPE_ONE_POINT_TRIMMING; 551 break; | |
552 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: | 544 case EXYNOS5433_TRIMINFO_TWO_POINT_TRIMMING: |
553 pdata->cal_type = TYPE_TWO_POINT_TRIMMING; | 545 data->cal_type = TYPE_TWO_POINT_TRIMMING; |
554 break; | 546 break; |
547 case EXYNOS5433_TRIMINFO_ONE_POINT_TRIMMING: |
|
555 default: | 548 default: |
556 pdata->cal_type = TYPE_ONE_POINT_TRIMMING; | 549 data->cal_type = TYPE_ONE_POINT_TRIMMING; |
557 break; 558 } 559 560 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", 561 cal_type ? 2 : 1); 562 563 /* Write temperature code for rising and falling threshold */ 564 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { --- 563 unchanged lines hidden (view full) --- 1128 }, { 1129 .compatible = "samsung,exynos7-tmu", 1130 .data = (const void *)SOC_ARCH_EXYNOS7, 1131 }, 1132 { }, 1133}; 1134MODULE_DEVICE_TABLE(of, exynos_tmu_match); 1135 | 550 break; 551 } 552 553 dev_info(&pdev->dev, "Calibration type is %d-point calibration\n", 554 cal_type ? 2 : 1); 555 556 /* Write temperature code for rising and falling threshold */ 557 for (i = 0; i < of_thermal_get_ntrips(tz); i++) { --- 563 unchanged lines hidden (view full) --- 1121 }, { 1122 .compatible = "samsung,exynos7-tmu", 1123 .data = (const void *)SOC_ARCH_EXYNOS7, 1124 }, 1125 { }, 1126}; 1127MODULE_DEVICE_TABLE(of, exynos_tmu_match); 1128 |
1136static int exynos_of_sensor_conf(struct device_node *np, 1137 struct exynos_tmu_platform_data *pdata) 1138{ 1139 of_node_get(np); 1140 1141 of_property_read_u32(np, "samsung,tmu_cal_type", &pdata->cal_type); 1142 1143 of_node_put(np); 1144 return 0; 1145} 1146 | |
1147static int exynos_map_dt_data(struct platform_device *pdev) 1148{ 1149 struct exynos_tmu_data *data = platform_get_drvdata(pdev); | 1129static int exynos_map_dt_data(struct platform_device *pdev) 1130{ 1131 struct exynos_tmu_data *data = platform_get_drvdata(pdev); |
1150 struct exynos_tmu_platform_data *pdata; | |
1151 struct resource res; 1152 1153 if (!data || !pdev->dev.of_node) 1154 return -ENODEV; 1155 1156 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 1157 if (data->id < 0) 1158 data->id = 0; --- 10 unchanged lines hidden (view full) --- 1169 } 1170 1171 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 1172 if (!data->base) { 1173 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 1174 return -EADDRNOTAVAIL; 1175 } 1176 | 1132 struct resource res; 1133 1134 if (!data || !pdev->dev.of_node) 1135 return -ENODEV; 1136 1137 data->id = of_alias_get_id(pdev->dev.of_node, "tmuctrl"); 1138 if (data->id < 0) 1139 data->id = 0; --- 10 unchanged lines hidden (view full) --- 1150 } 1151 1152 data->base = devm_ioremap(&pdev->dev, res.start, resource_size(&res)); 1153 if (!data->base) { 1154 dev_err(&pdev->dev, "Failed to ioremap memory\n"); 1155 return -EADDRNOTAVAIL; 1156 } 1157 |
1177 pdata = devm_kzalloc(&pdev->dev, 1178 sizeof(struct exynos_tmu_platform_data), 1179 GFP_KERNEL); 1180 if (!pdata) 1181 return -ENOMEM; 1182 1183 exynos_of_sensor_conf(pdev->dev.of_node, pdata); 1184 data->pdata = pdata; | |
1185 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); 1186 1187 switch (data->soc) { 1188 case SOC_ARCH_EXYNOS4210: 1189 data->tmu_initialize = exynos4210_tmu_initialize; 1190 data->tmu_control = exynos4210_tmu_control; 1191 data->tmu_read = exynos4210_tmu_read; 1192 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; --- 68 unchanged lines hidden (view full) --- 1261 data->min_efuse_value = 15; 1262 data->max_efuse_value = 100; 1263 break; 1264 default: 1265 dev_err(&pdev->dev, "Platform not supported\n"); 1266 return -EINVAL; 1267 } 1268 | 1158 data->soc = (enum soc_type)of_device_get_match_data(&pdev->dev); 1159 1160 switch (data->soc) { 1161 case SOC_ARCH_EXYNOS4210: 1162 data->tmu_initialize = exynos4210_tmu_initialize; 1163 data->tmu_control = exynos4210_tmu_control; 1164 data->tmu_read = exynos4210_tmu_read; 1165 data->tmu_clear_irqs = exynos4210_tmu_clear_irqs; --- 68 unchanged lines hidden (view full) --- 1234 data->min_efuse_value = 15; 1235 data->max_efuse_value = 100; 1236 break; 1237 default: 1238 dev_err(&pdev->dev, "Platform not supported\n"); 1239 return -EINVAL; 1240 } 1241 |
1242 data->cal_type = TYPE_ONE_POINT_TRIMMING; 1243 |
|
1269 /* 1270 * Check if the TMU shares some registers and then try to map the 1271 * memory of common registers. 1272 */ 1273 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && 1274 data->soc != SOC_ARCH_EXYNOS5440) 1275 return 0; 1276 --- 208 unchanged lines hidden --- | 1244 /* 1245 * Check if the TMU shares some registers and then try to map the 1246 * memory of common registers. 1247 */ 1248 if (data->soc != SOC_ARCH_EXYNOS5420_TRIMINFO && 1249 data->soc != SOC_ARCH_EXYNOS5440) 1250 return 0; 1251 --- 208 unchanged lines hidden --- |